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

Open
zemega opened this issue Apr 4, 2022 · 7 comments
Open

Multiple new_scale_fill doesn't work. #45

zemega opened this issue Apr 4, 2022 · 7 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/ggnewscale@v0.4.3")

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!

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

3 participants