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

annotation_logticks with marginal plots #141

Open
skinnider opened this issue Jul 15, 2019 · 8 comments
Open

annotation_logticks with marginal plots #141

skinnider opened this issue Jul 15, 2019 · 8 comments

Comments

@skinnider
Copy link

When inserting grobs into the left and bottom positions of the “main” plot panel, the axes are automatically adjusted to align with the “main” panel. However, the same behaviour doesn’t occur for annotation_logticks, which spill over into the inserted grobs.

I would like to achieve an effect where the annotation_logticks has the boundaries of the ones in the inner panel in the minimal example shown below, but is aligned with the axes. Is this possible?

library(tidyverse)
library(cowplot)
#> 
#> Attaching package: 'cowplot'
#> The following object is masked from 'package:ggplot2':
#> 
#>     ggsave
x = 10 ^ rnorm(100)
y = 10 ^ rnorm(100)
x[x > 1] = 1
y[y > 1] = 1
x[sample(seq_along(x), 40)] = NA
y[sample(seq_along(y), 40)] = NA
dat = data.frame(x = x, y = y)

dat1 = filter(dat, !is.na(x), !is.na(y))
dat2 = filter(dat, is.na(x), !is.na(y))
dat3 = filter(dat, !is.na(x), is.na(y))

# base plot
p_base = ggplot(dat1, aes(x = x, y = y)) + 
  geom_point() +
  scale_x_log10() +
  scale_y_log10() +
  annotation_logticks(sides = 'bl')  +
  theme_cowplot()

# marginal plots
p_y = axis_canvas(p_base, axis = "y") +
  geom_jitter(data = dat2, aes(x = 1, y = y), width = 0.05,
              color = 'blue') +
  scale_y_log10() +
  scale_x_continuous(limits = c(0.9, 1.1)) +
  annotation_logticks(sides = 'l')  +
  theme_cowplot()
#> Scale for 'y' is already present. Adding another scale for 'y', which
#> will replace the existing scale.
#> Scale for 'x' is already present. Adding another scale for 'x', which
#> will replace the existing scale.
p_x = axis_canvas(p_base, axis = "x") +
  geom_jitter(data = dat3, aes(x = x, y = 1), width = 0.05,
              color = 'red') +
  scale_x_log10() +
  scale_y_continuous(limits = c(0.9, 1.1)) +
  annotation_logticks(sides = 'b')  +
  theme_cowplot()
#> Scale for 'x' is already present. Adding another scale for 'x', which
#> will replace the existing scale.
#> Scale for 'y' is already present. Adding another scale for 'y', which
#> will replace the existing scale.

# combine
p = p_base %>%
  insert_yaxis_grob(p_y, position = "left") %>%
  insert_xaxis_grob(p_x, position = "bottom")
#> Warning: Removed 20 rows containing missing values (geom_point).
ggdraw(p)

Created on 2019-07-15 by the reprex package (v0.2.1)

@clauswilke
Copy link
Contributor

Copying scales is difficult. You'll probably see better results if you're not using axis_canvas() at all but instead use ggplot() directly for the marginal plots. Just make sure you set the exact same scales for all plots. You'll have to explicitly set limits to make sure the ranges match.

@skinnider
Copy link
Author

I might be misunderstanding something but replacing axis_canvas() with ggplot() doesn't seem to change the behaviour of annotation_logticks:

library(tidyverse)
library(cowplot)
#> 
#> ********************************************************
#> Note: As of version 1.0.0, cowplot does not change the
#>   default ggplot2 theme anymore. To recover the previous
#>   behavior, execute:
#>   theme_set(theme_cowplot())
#> ********************************************************

x = 10 ^ rnorm(100)
y = 10 ^ rnorm(100)
x[x > 1] = 1
y[y > 1] = 1
x[sample(seq_along(x), 40)] = NA
y[sample(seq_along(y), 40)] = NA
dat = data.frame(x = x, y = y)

dat1 = filter(dat, !is.na(x), !is.na(y))
dat2 = filter(dat, is.na(x), !is.na(y))
dat3 = filter(dat, !is.na(x), is.na(y))

# base plot
p_base = ggplot(dat1, aes(x = x, y = y)) + 
  geom_point() +
  scale_x_log10(limits = c(1e-3, 1)) +
  scale_y_log10(limits = c(1e-3, 1)) +
  annotation_logticks(sides = 'bl')  +
  theme_cowplot()

# marginal plots
p_y = ggplot(dat2, aes(x = 1, y = y)) +
  geom_jitter(width = 0.05, color = 'blue') +
  scale_y_log10(limits = c(1e-3, 1)) +
  scale_x_continuous(limits = c(0.9, 1.1)) +
  annotation_logticks(sides = 'l')  +
  theme_cowplot()
p_x = ggplot(dat3, aes(x = x, y = 1)) +
  geom_jitter(width = 0.05, color = 'red') +
  scale_x_log10(limits = c(1e-3, 1)) +
  scale_y_continuous(limits = c(0.9, 1.1)) +
  annotation_logticks(sides = 'b')  +
  theme_cowplot()

# combine
p = p_base %>%
  insert_yaxis_grob(p_y, position = "left") %>%
  insert_xaxis_grob(p_x, position = "bottom")
#> Warning: Removed 5 rows containing missing values (geom_point).
#> Warning: Removed 15 rows containing missing values (geom_point).
ggdraw(p)

Created on 2019-07-15 by the reprex package (v0.2.1)

@clauswilke
Copy link
Contributor

I get it now. Fixed in master.

library(tidyverse)
library(cowplot)
#> 
#> ********************************************************
#> Note: As of version 1.0.0, cowplot does not change the
#>   default ggplot2 theme anymore. To recover the previous
#>   behavior, execute:
#>   theme_set(theme_cowplot())
#> ********************************************************

x = 10 ^ rnorm(100)
y = 10 ^ rnorm(100)
x[x > 1] = 1
y[y > 1] = 1
x[sample(seq_along(x), 40)] = NA
y[sample(seq_along(y), 40)] = NA
dat = data.frame(x = x, y = y)

dat1 = filter(dat, !is.na(x), !is.na(y))
dat2 = filter(dat, is.na(x), !is.na(y))
dat3 = filter(dat, !is.na(x), is.na(y))

# base plot
p_base = ggplot(dat1, aes(x = x, y = y)) + 
  geom_point() +
  scale_x_log10(limits = c(1e-3, 1)) +
  scale_y_log10(limits = c(1e-3, 1)) +
  annotation_logticks(sides = 'bl')  +
  theme_cowplot()

# marginal plots
p_y = ggplot(dat2, aes(x = 1, y = y)) +
  geom_jitter(width = 0.05, color = 'blue') +
  scale_y_log10(limits = c(1e-3, 1)) +
  scale_x_continuous(limits = c(0.9, 1.1)) +
  annotation_logticks(sides = 'l')  +
  theme_cowplot()
p_x = ggplot(dat3, aes(x = x, y = 1)) +
  geom_jitter(width = 0.05, color = 'red') +
  scale_x_log10(limits = c(1e-3, 1)) +
  scale_y_continuous(limits = c(0.9, 1.1)) +
  annotation_logticks(sides = 'b')  +
  theme_cowplot()

# combine
p = p_base %>%
  insert_yaxis_grob(p_y, position = "left") %>%
  insert_xaxis_grob(p_x, position = "bottom")
#> Warning: Removed 5 rows containing missing values (geom_point).
#> Warning: Removed 19 rows containing missing values (geom_point).
ggdraw(p)

Created on 2019-07-15 by the reprex package (v0.3.0)

@skinnider
Copy link
Author

Thanks!

@skinnider
Copy link
Author

This issue seems to be recurring with cowplot 1.0.0 and ggplot2 3.3.0:

library(tidyverse)
library(cowplot)
#> 
#> ********************************************************
#> Note: As of version 1.0.0, cowplot does not change the
#>   default ggplot2 theme anymore. To recover the previous
#>   behavior, execute:
#>   theme_set(theme_cowplot())
#> ********************************************************
x = 10 ^ rnorm(100)
y = 10 ^ rnorm(100)
x[x > 1] = 1
y[y > 1] = 1
x[sample(seq_along(x), 40)] = NA
y[sample(seq_along(y), 40)] = NA
dat = data.frame(x = x, y = y)

dat1 = filter(dat, !is.na(x), !is.na(y))
dat2 = filter(dat, is.na(x), !is.na(y))
dat3 = filter(dat, !is.na(x), is.na(y))

# base plot
p_base = ggplot(dat1, aes(x = x, y = y)) + 
  geom_point() +
  scale_x_log10() +
  scale_y_log10() +
  annotation_logticks(sides = 'bl')  +
  theme_cowplot()

# marginal plots
p_y = axis_canvas(p_base, axis = "y") +
  geom_jitter(data = dat2, aes(x = 1, y = y), width = 0.05,
              color = 'blue') +
  scale_y_log10() +
  scale_x_continuous(limits = c(0.9, 1.1)) +
  annotation_logticks(sides = 'l')  +
  theme_cowplot()
#> Scale for 'y' is already present. Adding another scale for 'y', which will
#> replace the existing scale.
#> Scale for 'x' is already present. Adding another scale for 'x', which will
#> replace the existing scale.
p_x = axis_canvas(p_base, axis = "x") +
  geom_jitter(data = dat3, aes(x = x, y = 1), width = 0.05,
              color = 'red') +
  scale_x_log10() +
  scale_y_continuous(limits = c(0.9, 1.1)) +
  annotation_logticks(sides = 'b')  +
  theme_cowplot()
#> Scale for 'x' is already present. Adding another scale for 'x', which will
#> replace the existing scale.
#> Scale for 'y' is already present. Adding another scale for 'y', which will
#> replace the existing scale.

# combine
p = p_base %>%
  insert_yaxis_grob(p_y, position = "left") %>%
  insert_xaxis_grob(p_x, position = "bottom")
#> Warning: Removed 18 rows containing missing values (geom_point).
ggdraw(p)

Created on 2020-05-19 by the reprex package (v0.3.0)

sessionInfo():

R version 3.6.3 (2020-02-29)
Platform: x86_64-apple-darwin15.6.0 (64-bit)
Running under: macOS High Sierra 10.13.6

Matrix products: default
BLAS:   /Library/Frameworks/R.framework/Versions/3.6/Resources/lib/libRblas.0.dylib
LAPACK: /Library/Frameworks/R.framework/Versions/3.6/Resources/lib/libRlapack.dylib

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

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

other attached packages:
 [1] cowplot_1.0.0   forcats_0.5.0   stringr_1.4.0   dplyr_0.8.5     purrr_0.3.3     readr_1.3.1     tidyr_1.0.2     tibble_3.0.0   
 [9] ggplot2_3.3.0   tidyverse_1.3.0

loaded via a namespace (and not attached):
 [1] Rcpp_1.0.4.6     cellranger_1.1.0 pillar_1.4.3     compiler_3.6.3   dbplyr_1.4.2     tools_3.6.3      digest_0.6.25    lubridate_1.7.8 
 [9] jsonlite_1.6.1   lifecycle_0.2.0  nlme_3.1-145     gtable_0.3.0     lattice_0.20-40  pkgconfig_2.0.3  rlang_0.4.5      reprex_0.3.0    
[17] rstudioapi_0.11  cli_2.0.2        DBI_1.1.0        haven_2.2.0      withr_2.1.2      xml2_1.2.5       httr_1.4.1       fs_1.3.2        
[25] generics_0.0.2   vctrs_0.2.4      hms_0.5.3        grid_3.6.3       tidyselect_1.0.0 glue_1.4.0       R6_2.4.1         fansi_0.4.1     
[33] readxl_1.3.1     farver_2.0.3     modelr_0.1.6     magrittr_1.5     backports_1.1.6  scales_1.1.0     ellipsis_0.3.0   rvest_0.3.5     
[41] assertthat_0.2.1 colorspace_1.4-1 labeling_0.3     stringi_1.4.6    munsell_0.5.0    broom_0.5.5      crayon_1.3.4    

@clauswilke
Copy link
Contributor

Seems to be a different problem than before because the logticks are also misaligned now. Actually, I now think that the patchwork library is a better approach for this type of plot. Have you tried using patchwork?

@clauswilke clauswilke reopened this May 19, 2020
@skinnider
Copy link
Author

Oops, the log-ticks misalignment was just because I forgot to set the axis limits in the base plot:

library(tidyverse)
library(cowplot)
#> 
#> ********************************************************
#> Note: As of version 1.0.0, cowplot does not change the
#>   default ggplot2 theme anymore. To recover the previous
#>   behavior, execute:
#>   theme_set(theme_cowplot())
#> ********************************************************
x = 10 ^ rnorm(100)
y = 10 ^ rnorm(100)
x[x > 1] = 1
y[y > 1] = 1
x[sample(seq_along(x), 40)] = NA
y[sample(seq_along(y), 40)] = NA
dat = data.frame(x = x, y = y)

dat1 = filter(dat, !is.na(x), !is.na(y))
dat2 = filter(dat, is.na(x), !is.na(y))
dat3 = filter(dat, !is.na(x), is.na(y))

# base plot
p_base = ggplot(dat1, aes(x = x, y = y)) + 
  geom_point() +
  scale_x_log10(limits = c(1e-3, 1)) +
  scale_y_log10(limits = c(1e-3, 1)) +
  annotation_logticks(sides = 'bl')  +
  theme_cowplot()

# marginal plots
p_y = ggplot(dat2, aes(x = 1, y = y)) +
  geom_jitter(width = 0.05, color = 'blue') +
  scale_y_log10(limits = c(1e-3, 1)) +
  scale_x_continuous(limits = c(0.9, 1.1)) +
  annotation_logticks(sides = 'l')  +
  theme_cowplot()
p_x = ggplot(dat3, aes(x = x, y = 1)) +
  geom_jitter(width = 0.05, color = 'red') +
  scale_x_log10(limits = c(1e-3, 1)) +
  scale_y_continuous(limits = c(0.9, 1.1)) +
  annotation_logticks(sides = 'b')  +
  theme_cowplot()

# combine
p = p_base %>%
  insert_yaxis_grob(p_y, position = "left") %>%
  insert_xaxis_grob(p_x, position = "bottom")
#> Warning: Removed 4 rows containing missing values (geom_point).
#> Warning: Removed 17 rows containing missing values (geom_point).
ggdraw(p)

Created on 2020-05-21 by the reprex package (v0.3.0)

Yes, I can just update the code to use patchwork instead. I would still be interested to understand why exactly this is breaking, though, because I wonder if it’s related to some other issues I’ve been having with ggplot2 since the version 3 release (as far as I can tell, the insert_*axis_grob code doesn't seem to have changed).

@clauswilke
Copy link
Contributor

So I can't reproduce this, actually. Which version of R are you using? I'm still at 3.6. If you're at 4.0, maybe something has changed in how clipping works in grid? You could try ggdraw(p, clip = "on") and see if that helps.

library(tidyverse)
library(cowplot)
#> 
#> ********************************************************
#> Note: As of version 1.0.0, cowplot does not change the
#>   default ggplot2 theme anymore. To recover the previous
#>   behavior, execute:
#>   theme_set(theme_cowplot())
#> ********************************************************

x = 10 ^ rnorm(100)
y = 10 ^ rnorm(100)
x[x > 1] = 1
y[y > 1] = 1
x[sample(seq_along(x), 40)] = NA
y[sample(seq_along(y), 40)] = NA
dat = data.frame(x = x, y = y)

dat1 = filter(dat, !is.na(x), !is.na(y))
dat2 = filter(dat, is.na(x), !is.na(y))
dat3 = filter(dat, !is.na(x), is.na(y))

# base plot
p_base = ggplot(dat1, aes(x = x, y = y)) + 
  geom_point() +
  scale_x_log10(limits = c(1e-3, 1)) +
  scale_y_log10(limits = c(1e-3, 1)) +
  annotation_logticks(sides = 'bl')  +
  theme_cowplot()

# marginal plots
p_y = ggplot(dat2, aes(x = 1, y = y)) +
  geom_jitter(width = 0.05, color = 'blue') +
  scale_y_log10(limits = c(1e-3, 1)) +
  scale_x_continuous(limits = c(0.9, 1.1)) +
  annotation_logticks(sides = 'l')  +
  theme_cowplot()
p_x = ggplot(dat3, aes(x = x, y = 1)) +
  geom_jitter(width = 0.05, color = 'red') +
  scale_x_log10(limits = c(1e-3, 1)) +
  scale_y_continuous(limits = c(0.9, 1.1)) +
  annotation_logticks(sides = 'b')  +
  theme_cowplot()

# combine
p = p_base %>%
  insert_yaxis_grob(p_y, position = "left") %>%
  insert_xaxis_grob(p_x, position = "bottom")
#> Warning: Removed 8 rows containing missing values (geom_point).
#> Warning: Removed 19 rows containing missing values (geom_point).

ggdraw(p)

Created on 2020-05-21 by the reprex package (v0.3.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

2 participants