Home > Software engineering >  ggplot cowplot ensuring y axes are identical when arranging plots with log scale
ggplot cowplot ensuring y axes are identical when arranging plots with log scale

Time:08-19

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!

CodePudding user response:

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.

  • Related