Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ggplot sec_axis does not work with transformations that raise the axis to a power in version 3.1

Tags:

r

ggplot2

I'm using ggplot2 to plot log2 transformed data but would also like to show the untransformed equivalent values as a secondary axis. Since the data is already log2 transformed, I should be able to reverse the transformation by raising 2 to that power (~2^.). This worked very nicely in version 3.0.0, but after upgrading to 3.1.0, this code produces no errors but makes a secondary axis that doesn't make any sense:

df = data.frame(x = rnorm(100),
                y = rnorm(100))

ggplot(df, aes(x,y)) +
      geom_point() +
      scale_y_continuous(sec.axis = sec_axis(trans=(~2^.)))

enter image description here

Secondary axes work normally with other formulas (~., ~. + 10, and ~ . * 10 all work as expected), only ~2^. is giving me any problems.


I'm pretty sure this is related to upgrading to version 3.1 since in according to the release notes, there was a change related specifically to using sec_axis with log transformed data, but I can't figure out what was changed and why it's behaving the way is does now. Does anyone know more about this, or have any idea of a workaround other than downgrading to 3.0?

> sessionInfo()
R version 3.5.1 (2018-07-02)
Platform: x86_64-apple-darwin15.6.0 (64-bit)
Running under: macOS High Sierra 10.13.6

Matrix products: default
BLAS: /System/Library/Frameworks/Accelerate.framework/Versions/A/Frameworks/vecLib.framework/Versions/A/libBLAS.dylib
LAPACK: /Library/Frameworks/R.framework/Versions/3.5/Resources/lib/libRlapack.dylib

locale:
[1] en_US.UTF-8/en_US.UTF-8/en_US.UTF-8/C/en_US.UTF-8/en_US.UTF-8

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

other attached packages:
[1] ggplot2_3.1.0

loaded via a namespace (and not attached):
 [1] Rcpp_0.12.19     withr_2.1.2      assertthat_0.2.0 crayon_1.3.4     dplyr_0.7.7      R6_2.3.0         grid_3.5.1      
 [8] plyr_1.8.4       gtable_0.2.0     magrittr_1.5     scales_1.0.0     pillar_1.3.0     rlang_0.3.0.1    lazyeval_0.2.1  
[15] rstudioapi_0.7   bindrcpp_0.2.2   labeling_0.3     tools_3.5.1      glue_1.3.0       purrr_0.2.5      munsell_0.5.0   
[22] yaml_2.2.0       compiler_3.5.1   pkgconfig_2.0.2  colorspace_1.3-2 tidyselect_0.2.5 bindr_0.1.1      tibble_1.4.2  
like image 436
divibisan Avatar asked Mar 06 '23 03:03

divibisan


2 Answers

As mentioned in the comments, this is currently a bug with ggplot2 version 3.1.0.

For now, a simple workaround for your case is to just pre-define your desired break positions, where they would occur in untransformed space, and then perform the desired transform. Using the breaks argument is necessary to get the positioning correct.

Try this code:

library("ggplot2")

set.seed(7)
# Create some log (base 2) transformed data
df = data.frame(x = log2(runif(100, min = 0, max = 10)),
                y = log2(runif(100, min = 0, max = 10)))

# A vector of your desired break positions in untransformed space
sec_breaks <- c(0.4,0.5,1,2,4,8,10)
# Transform break positions
scaled_breaks <- log2(sec_breaks)

ggplot(df, aes(x,y)) +
  geom_point() +
  scale_y_continuous(sec.axis = sec_axis(trans = (~.),
                                         breaks = scaled_breaks,
                                         labels = sprintf("%.1f", sec_breaks)))

Which gives this plot:

enter image description here

like image 180
Marcus Campbell Avatar answered Mar 11 '23 05:03

Marcus Campbell


This bug has been fixed. In the newest version of ggplot (3.2.1), the following code now correctly renders the secondary axis:

df = data.frame(x = rnorm(100),
                y = rnorm(100))

ggplot(df, aes(x,y)) +
      geom_point() +
      scale_y_continuous(sec.axis = sec_axis(trans=(~2^.)))

enter image description here

like image 24
divibisan Avatar answered Mar 11 '23 04:03

divibisan