Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Multiple new_scale_fill doesn't work. #45

Closed
zemega opened this issue Apr 4, 2022 · 10 comments
Closed

Multiple new_scale_fill doesn't work. #45

zemega opened this issue Apr 4, 2022 · 10 comments

Comments

@zemega
Copy link

zemega commented Apr 4, 2022

Hello. I ran into a problem with using multiple new_scale_fill. It doesn't seems to work for me when I used more than two. Please see the example belows.

plot_data <-
  data.table(X = c(rnorm(300, 5, 2), rnorm(300,  5, 2),rnorm(300,  5, 2),rnorm(300,  5, 2)),
             Y = c(rnorm(300, 5, 1), rnorm(300, 10, 1),rnorm(300, 15, 1),rnorm(300, 20, 1)),
             Label = c(rep('A', 300), rep('B', 300), rep('C', 300), rep('D', 300)))

Using fill under ggplot. There's 4 groups.

ggplot(data=plot_data, aes(x=X, y=Y,fill=Label)) + 
  geom_bin2d() 

image

Using a single new_scale_fill

ggplot() +
  new_scale_fill() +
  geom_bin2d(data=plot_data[Label=="A"],aes(x=X, y=Y))+
  scale_fill_continuous(low = "red", high = "white")

image

Using two new_scale_fill

ggplot() +
  new_scale_fill() +
  geom_bin2d(data=plot_data[Label=="A"],aes(x=X, y=Y))+
  scale_fill_continuous(low = "red", high = "white")+
  
  new_scale_fill() +
  geom_bin2d(data=plot_data[Label=="B"],aes(x=X, y=Y))+
  scale_fill_continuous(low = "green", high = "white") 

image

Using three new_scale_fill

ggplot() +
  new_scale_fill() +
  geom_bin2d(data=plot_data[Label=="A"],aes(x=X, y=Y))+
  scale_fill_continuous(low = "red", high = "white")+
  
  new_scale_fill() +
  geom_bin2d(data=plot_data[Label=="B"],aes(x=X, y=Y))+
  scale_fill_continuous(low = "green", high = "white") +
  
  new_scale_fill() +
  geom_bin2d(data=plot_data[Label=="C"],aes(x=X, y=Y))+
  scale_fill_continuous(low = "blue", high = "white") 

image
Using four new_scale_fill

ggplot() +
  new_scale_fill() +
  geom_bin2d(data=plot_data[Label=="A"],aes(x=X, y=Y))+
  scale_fill_continuous(low = "red", high = "white")+
  
  new_scale_fill() +
  geom_bin2d(data=plot_data[Label=="B"],aes(x=X, y=Y))+
  scale_fill_continuous(low = "green", high = "white") +
  
  new_scale_fill() +
  geom_bin2d(data=plot_data[Label=="C"],aes(x=X, y=Y))+
  scale_fill_continuous(low = "blue", high = "white") +
  
  new_scale_fill() +
  geom_bin2d(data=plot_data[Label=="D"],aes(x=X, y=Y))+
  scale_fill_continuous(low = "purple", high = "white")

image

I'm taking this approach because I want to use new_scale_fill in a for loop situation. Such as below.

Main=ggplot()

for(count in 1:4){
  Main =Main + new_scale_fill() +
  geom_bin2d(data=plot_data[Label==Group_Information[count]],aes(x=X, y=Y))+
  scale_fill_continuous(low = Colours[count], high = "white")
}
Main
#The output is the same as the figure above.

As you can see, when using multiple new_scale_fill, the output was not what I was expecting, something similar to the first figure. I tried going through stackoverflow.com, but most example are only using two new_scale_fill.

sessionInfo()
R version 4.0.2 (2020-06-22)
Platform: x86_64-w64-mingw32/x64 (64-bit)
Running under: Windows 10 x64 (build 19043)

Matrix products: default

locale:
[1] LC_COLLATE=English_Malaysia.1252  LC_CTYPE=English_Malaysia.1252    LC_MONETARY=English_Malaysia.1252
[4] LC_NUMERIC=C                      LC_TIME=English_Malaysia.1252    

attached base packages:
[1] stats     graphics  grDevices utils     datasets  methods   base     

other attached packages:
[1] ggnewscale_0.4.7  ggplot2_3.3.5     data.table_1.14.0

loaded via a namespace (and not attached):
 [1] knitr_1.37       magrittr_2.0.1   tidyselect_1.1.1 munsell_0.5.0    colorspace_2.0-1 R6_2.5.0        
 [7] rlang_0.4.11     fansi_0.5.0      dplyr_1.0.6      tools_4.0.2      grid_4.0.2       gtable_0.3.0    
[13] xfun_0.29        utf8_1.2.1       DBI_1.1.1        withr_2.4.2      ellipsis_0.3.2   digest_0.6.27   
[19] assertthat_0.2.1 tibble_3.1.2     lifecycle_1.0.0  crayon_1.4.1     farver_2.1.0     purrr_0.3.4     
[25] vctrs_0.3.8      glue_1.4.2       labeling_0.4.2   compiler_4.0.2   pillar_1.6.1     generics_0.1.0  
[31] scales_1.1.1     pkgconfig_2.0.3 
@eliocamp
Copy link
Owner

eliocamp commented Apr 4, 2022

Thanks for the report.
It should work with as many as you'd like. This seems like a regression. Running your examples in previous versions, the last version without this bug is 0.4.3. So as a workaround you can install that version with:

devtools::install_github("eliocamp/[email protected]")

Output:

library(data.table)
library(ggplot2)
library(ggnewscale)
packageVersion("ggnewscale")
#> [1] '0.4.3'

plot_data <-
  data.table(X = c(rnorm(300, 5, 2), rnorm(300,  5, 2),rnorm(300,  5, 2),rnorm(300,  5, 2)),
             Y = c(rnorm(300, 5, 1), rnorm(300, 10, 1),rnorm(300, 15, 1),rnorm(300, 20, 1)),
             Label = c(rep('A', 300), rep('B', 300), rep('C', 300), rep('D', 300)))
             
ggplot() +
  new_scale_fill() +
  geom_bin2d(data=plot_data[Label=="A"],aes(x=X, y=Y))+
  scale_fill_continuous(low = "red", high = "white")+
  
  new_scale_fill() +
  geom_bin2d(data=plot_data[Label=="B"],aes(x=X, y=Y))+
  scale_fill_continuous(low = "green", high = "white") +
  
  new_scale_fill() +
  geom_bin2d(data=plot_data[Label=="C"],aes(x=X, y=Y))+
  scale_fill_continuous(low = "blue", high = "white") +
  
  new_scale_fill() +
  geom_bin2d(data=plot_data[Label=="D"],aes(x=X, y=Y))+
  scale_fill_continuous(low = "purple", high = "white")

Created on 2022-04-04 by the reprex package (v2.0.1)

@zemega
Copy link
Author

zemega commented Apr 4, 2022

Just installed version 0.4.3, and it runs as intended. Thank you for your help.

@eliocamp
Copy link
Owner

eliocamp commented May 8, 2023

Update to this bug: It seems to be caused by default mapping. Summary:

library(data.table)
library(ggplot2)
library(ggnewscale)
packageVersion("ggnewscale")
#> [1] '0.4.8.9000'
set.seed(42)

plot_data <-
  data.table(X = c(rnorm(300, 5, 2), rnorm(300,  5, 2),rnorm(300,  5, 2),rnorm(300,  5, 2)),
             Y = c(rnorm(300, 5, 1), rnorm(300, 10, 1),rnorm(300, 15, 1),rnorm(300, 20, 1)),
             Label = c(rep('A', 300), rep('B', 300), rep('C', 300), rep('D', 300)))

Adding one extra scale works correctly

ggplot(mapping = aes(x = X, y = Y)) +
  geom_bin2d(data = plot_data[Label=="A"]) +
  scale_fill_continuous("1", low = "red", high = "white") +
  
  new_scale_fill() +
  geom_bin2d(data = plot_data[Label=="B"]) +
  scale_fill_continuous("2", low = "green", high = "white")

But adding an extra one breaks everything

ggplot(mapping = aes(x = X, y = Y)) +
  geom_bin2d(data = plot_data[Label=="A"]) +
  scale_fill_continuous("1", low = "red", high = "white") +
  
  new_scale_fill() +
  geom_bin2d(data = plot_data[Label=="B"]) +
  scale_fill_continuous("2", low = "green", high = "white") +
  
  new_scale_fill() +
  geom_bin2d(data = plot_data[Label=="C"]) +
  scale_fill_continuous("3", low = "blue", high = "white") 

This still works with explicit mapping

ggplot(mapping = aes(x = X, y = Y)) +
  geom_bin2d(data = plot_data[Label=="A"], aes(fill = after_stat(count))) +
  scale_fill_continuous("1", low = "red", high = "white") +
  
  new_scale_fill() +
  geom_bin2d(data = plot_data[Label=="B"], aes(fill = after_stat(count))) +
  scale_fill_continuous("2", low = "green", high = "white") +
  
  new_scale_fill() +
  geom_bin2d(data = plot_data[Label=="C"], aes(fill = after_stat(count))) +
  scale_fill_continuous("3", low = "blue", high = "white") 

Created on 2023-05-08 with reprex v2.0.2

@eliocamp
Copy link
Owner

eliocamp commented May 8, 2023

Well, this took forever to fix, but it now is. The new version is on its way to CRAN.

@jan-glx
Copy link

jan-glx commented Jun 14, 2023

Not fully, I am afraid... There still is an issue e.g. when the third scale is discrete while 1 & 2 are continuous:

ggplot(mapping = aes(x = X, y = Y)) +
  geom_bin2d(data = plot_data[Label=="A"], aes(fill = after_stat(count))) +
  scale_fill_gradient("1", low = "red", high = "white") +
  
  new_scale_fill() +
  geom_bin2d(data = plot_data[Label=="B"], aes(fill = after_stat(count))) +
  scale_fill_discrete() +
  
  new_scale_fill() +
  geom_bin2d(data = plot_data[Label=="C"], aes(fill = after_stat(as.character(round(count))))) +
  scale_fill_discrete()

fails with Error: Continuous value supplied to discrete scale. (It does work as expected when commenting out the middle part). This is on latest master (‘0.4.9’).

@eliocamp eliocamp reopened this Jun 15, 2023
@eliocamp
Copy link
Owner

@jan-glx Your example fails in part because the second layer indeed uses a discrete scale for a continuous value. However, fixing that error shows that there's still an issue in ggnewscale.

library(data.table)
library(ggplot2)
library(ggnewscale)

plot_data <-
  data.table(X = c(rnorm(300, 5, 2), rnorm(300,  5, 2),rnorm(300,  5, 2),rnorm(300,  5, 2)),
             Y = c(rnorm(300, 5, 1), rnorm(300, 10, 1),rnorm(300, 15, 1),rnorm(300, 20, 1)),
             Label = c(rep('A', 300), rep('B', 300), rep('C', 300), rep('D', 300)))


ggplot(mapping = aes(x = X, y = Y)) +
  geom_bin2d(data = plot_data[Label=="A"], aes(fill = after_stat(count))) +
  scale_fill_gradient("1", low = "red", high = "white") +
  
  new_scale_fill() +
  geom_bin2d(data = plot_data[Label=="B"], aes(fill = after_stat(as.character(count)))) +
  scale_fill_discrete() +
  
  new_scale_fill() +
  geom_bin2d(data = plot_data[Label=="C"], aes(fill = after_stat(as.character(round(count))))) +
  scale_fill_discrete()
#> Error in `scale_fill_discrete()`:
#> ! Continuous values supplied to discrete scale
#> ℹ Example values: 1, 1, 1, 1, and 2
#> Backtrace:
#>      ▆
#>   1. ├─base::tryCatch(...)
#>   2. │ └─base (local) tryCatchList(expr, classes, parentenv, handlers)
#>   3. │   ├─base (local) tryCatchOne(...)
#>   4. │   │ └─base (local) doTryCatch(return(expr), name, parentenv, handler)
#>   5. │   └─base (local) tryCatchList(expr, names[-nh], parentenv, handlers[-nh])
#>   6. │     └─base (local) tryCatchOne(expr, names, parentenv, handlers[[1L]])
#>   7. │       └─base (local) doTryCatch(return(expr), name, parentenv, handler)
#>   8. ├─base::withCallingHandlers(...)
#>   9. ├─base::saveRDS(...)
#>  10. ├─base::do.call(...)
#>  11. ├─base (local) `<fn>`(...)
#>  12. └─global `<fn>`(input = base::quote("flat-ram_reprex.R"))
#>  13.   └─rmarkdown::render(input, quiet = TRUE, envir = globalenv(), encoding = "UTF-8")
#>  14.     └─knitr::knit(knit_input, knit_output, envir = envir, quiet = quiet)
#>  15.       └─knitr:::process_file(text, output)
#>  16.         ├─base::withCallingHandlers(...)
#>  17.         ├─base::withCallingHandlers(...)
#>  18.         ├─knitr:::process_group(group)
#>  19.         └─knitr:::process_group.block(group)
#>  20.           └─knitr:::call_block(x)
#>  21.             └─knitr:::block_exec(params)
#>  22.               └─knitr:::eng_r(options)
#>  23.                 ├─knitr:::in_input_dir(...)
#>  24.                 │ └─knitr:::in_dir(input_dir(), expr)
#>  25.                 └─knitr (local) evaluate(...)
#>  26.                   └─evaluate::evaluate(...)
#>  27.                     └─evaluate:::evaluate_call(...)
#>  28.                       ├─evaluate (local) handle(...)
#>  29.                       │ └─base::try(f, silent = TRUE)
#>  30.                       │   └─base::tryCatch(...)
#>  31.                       │     └─base (local) tryCatchList(expr, classes, parentenv, handlers)
#>  32.                       │       └─base (local) tryCatchOne(expr, names, parentenv, handlers[[1L]])
#>  33.                       │         └─base (local) doTryCatch(return(expr), name, parentenv, handler)
#>  34.                       ├─base::withCallingHandlers(...)
#>  35.                       ├─base::withVisible(value_fun(ev$value, ev$visible))
#>  36.                       └─knitr (local) value_fun(ev$value, ev$visible)
#>  37.                         └─knitr (local) fun(x, options = options)
#>  38.                           ├─base::withVisible(knit_print(x, ...))
#>  39.                           ├─knitr::knit_print(x, ...)
#>  40.                           └─knitr:::knit_print.default(x, ...)
#>  41.                             └─evaluate (local) normal_print(x)
#>  42.                               ├─base::print(x)
#>  43.                               └─ggplot2:::print.ggplot(x)
#>  44.                                 ├─ggplot2::ggplot_build(x)
#>  45.                                 └─ggplot2:::ggplot_build.ggplot(x)
#>  46.                                   └─base::lapply(data, npscales$train_df)
#>  47.                                     └─ggplot2 (local) FUN(X[[i]], ...)
#>  48.                                       └─ggplot2 (local) train_df(..., self = self)
#>  49.                                         └─base::lapply(self$scales, function(scale) scale$train_df(df = df))
#>  50.                                           └─ggplot2 (local) FUN(X[[i]], ...)
#>  51.                                             └─scale$train_df(df = df)
#>  52.                                               └─ggplot2 (local) train_df(..., self = self)
#>  53.                                                 └─self$train(df[[aesthetic]])
#>  54.                                                   └─ggplot2 (local) train(..., self = self)
#>  55.                                                     └─cli::cli_abort(...)
#>  56.                                                       └─rlang::abort(...)

The issue will be resolved in a new version which refactors the code and avoids a lot of the annoying logic that created this issue in the first place.

@jan-glx
Copy link

jan-glx commented Nov 22, 2023

Ooops, based on the text I wrote, I guess I meant the first scale_fill_discrete to be a continuous scale in which case it also fails with the same error message. Great to hear that you are working on it!

@HRodenhizer
Copy link

I'm having a similar issue which may already be solved by the planned changes, but the error message is different and I just wanted to make sure that it is considered. I run into this issue when the third new scale is provided as a string within the aesthetics (to provide the legend text for a single fill color, but I'm not sure what to call this).

library(data.table)
library(ggplot2)
library(ggnewscale)

plot_data <-
  data.table(X = c(rnorm(300, 5, 2), rnorm(300,  5, 2),rnorm(300,  5, 2),rnorm(300,  5, 2)),
             Y = c(rnorm(300, 5, 1), rnorm(300, 10, 1),rnorm(300, 15, 1),rnorm(300, 20, 1)),
             Label = c(rep('A', 300), rep('B', 300), rep('C', 300), rep('D', 300)))

ggplot(mapping = aes(x = X, y = Y)) +
  geom_bin2d(data = plot_data[Label=="A"], aes(fill = after_stat(count))) +
  scale_fill_gradient("1", low = "red", high = "white") +
  
  new_scale_fill() +
  geom_bin2d(data = plot_data[Label=="B"], aes(fill = after_stat(as.character(count)))) +
  scale_fill_discrete() +
  
  new_scale_fill() +
  geom_bin2d(data = plot_data[Label=="C"], aes(fill = 'C')) +
  scale_fill_manual(values = c('magenta'))
Error in scale$guide == "none" :
comparison (==) is possible only for atomic and list types

For comparison, the following works as expected:

ggplot(mapping = aes(x = X, y = Y)) +
  geom_bin2d(data = plot_data[Label=="A"], aes(fill = after_stat(count))) +
  scale_fill_gradient("1", low = "red", high = "white") +
  
  new_scale_fill() +
  geom_bin2d(data = plot_data[Label=="C"], aes(fill = 'C')) +
  scale_fill_manual(values = c('magenta'))

@Pacomito
Copy link

Pacomito commented May 22, 2024

Hello, I am having the same error as above, using ggnewscale as part of the FlowSOM package, which I think might be related to the same issue :

PlotStars(flowsom_model, backgroundValues = flowsom_model$metaclustering)

Erreur dans scale$guide == "none" :
comparison (==) is possible only for atomic and list types

12. isTRUE(scale$guide == "none")
11. FUN(X[[i]], ...)
10. lapply(scales, bump_aes_scale, new_aes = new_aes)
9. bump_aes_scales(plot$scales$scales, new_aes = object)
8. ggplot_add.new_aes(object, p, objectname)
7. ggplot_add(object, p, objectname)
6. add_ggplot(e1, e2, e2name)
5. `+.gg`(p, ggnewscale::new_scale(type))
4. AddScale(p = p, values = arcs$Markers, colors = colorPalette,
showLegend = showLegend)
3. AddStarsPies(p, starValues, colorPalette, showLegend = FALSE)
2. AddStars(p = p, fsom = fsom, markers = channels, colorPalette = colorPalette)
1. plotStars.(flowsom_model, backgroundValues = flowsom_model$metaclustering)

@eliocamp
Copy link
Owner

Hi! Thanks for the reports.

@HRodenhizer example works correctly in the current develompent version of ggnewscale. Note that ggplot2 changed their internals significantly so now ggnewscale requires ggplot2 3.5.0.

library(data.table)
#> Warning: package 'data.table' was built under R version 4.4.1
library(ggplot2)
library(ggnewscale)

plot_data <-
  data.table(X = c(rnorm(300, 5, 2), rnorm(300,  5, 2),rnorm(300,  5, 2),rnorm(300,  5, 2)),
             Y = c(rnorm(300, 5, 1), rnorm(300, 10, 1),rnorm(300, 15, 1),rnorm(300, 20, 1)),
             Label = c(rep('A', 300), rep('B', 300), rep('C', 300), rep('D', 300)))

ggplot(mapping = aes(x = X, y = Y)) +
  geom_bin2d(data = plot_data[Label=="A"], aes(fill = after_stat(count))) +
  scale_fill_gradient("1", low = "red", high = "white") +
  
  new_scale_fill() +
  geom_bin2d(data = plot_data[Label=="B"], aes(fill = after_stat(as.character(count)))) +
  scale_fill_discrete() +
  
  new_scale_fill() +
  geom_bin2d(data = plot_data[Label=="C"], aes(fill = 'C')) +
  scale_fill_manual(values = c('magenta'))

Created on 2024-07-18 with reprex v2.1.0

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants