0

I want to create a combination plot using plot_grid from the cowplot package. The two plots that I want to combine use a log scale. Of the data plotted, some is negative, which gets dropped.

I can quite easily produce a decent result using facet_wrap that looks like this:

library(tidyverse)
tibble(x = rnorm(100), 
       y = rnorm(100),
       type = "A") %>% 
  bind_rows(tibble(x = rnorm(100, mean = 10), 
                   y = rnorm(100, mean = 10),
                   type = "B")) %>% 
  
  ggplot(aes(y = y, x = x)) + 
  geom_point() + 
  facet_wrap(~type)

enter image description here

But in my particular situation, I can't use facet_wrap because I want to give the panels A and B different x-axis labels and want to change the number format slightly (e.g. adding a $ sign to the axis ticks of panel A and a % sign to panel B).

Therefore I use plot_grid:

tibble(x = rnorm(100), 
       y = rnorm(100),
       type = "A") %>% 
  ggplot(aes(y = y, x = x)) + 
  geom_point() + 
  scale_y_log10() -> a



tibble(x = rnorm(100, mean = 10), 
       y = rnorm(100, mean = 10),
       type = "B") %>% 
  ggplot(aes(y = y, x = x)) + 
  geom_point() + 
  scale_y_log10() -> b

cowplot::plot_grid(a,b)

enter image description here

Now the problem is that the axis is completely distorted (this would be equal to scales = "free_y" in facet_wrap)

So therefore I attempt to set the limits/ranges for both plots manually by choosing the min and max from both plots:

lims <- c(min(layer_scales(a)$y$range$range, layer_scales(b)$y$range$range),
          max(layer_scales(a)$y$range$range, layer_scales(b)$y$range$range))


cowplot::plot_grid(a + ylim(lims),b + ylim(lims))

But now the result is this:

enter image description here

So essentially I want to replicate the scales="fixed" in facet_wrap using plot_grid Any ideas?

many thanks!

Moritz Schwarz
  • 2,019
  • 2
  • 15
  • 33

1 Answers1

2

The issue is that you provide y axis limits in log10 scale as returned by layer_scales. You need to convert it to actual values.

lims = 10^c(min(layer_scales(a)$y$range$range, layer_scales(b)$y$range$range),
            max(layer_scales(a)$y$range$range, layer_scales(b)$y$range$range))

Alternatively, you can compute the range of the actual data.

yuk
  • 19,098
  • 13
  • 68
  • 99
  • That's excellent! I had played around with `exp` and other stuff but never really managed to get there. So many thanks for this quick reply! – Moritz Schwarz Aug 18 '22 at 19:13