2

How to align two plots with different widths so that:

  • their x-axes are in sync
  • the top row also contains a common legend

I basically want each x-axis-interval to correspond to the same amount of centimeters on the two plots. I have tried this:

library(cowplot)
library(tidyverse)    
wide_plot =  iris %>% 
    ggplot(aes(x = Sepal.Length, Sepal.Width, color = Species)) + 
      geom_point() + 
      theme(legend.position = "none") + 
      scale_x_continuous(limits = c(0,8))
    narrow_plot =  iris %>% 
    ggplot(aes(x = Sepal.Width, Sepal.Length, color = Species)) + 
      geom_point()  + 
      theme(legend.position = "none") + 
      scale_x_continuous(limits = c(0,5) )

    legend = cowplot::get_legend(ggplot(iris,aes(x = Sepal.Length, Sepal.Width, color = Species)) +  geom_point() )

    plot_grid(plot_grid(narrow_plot, legend), wide_plot, nrow = 2 ) 

Which produces this plot:

enter image description here

But the problem with the above is that the x-axis values on the top bottom plot are not 'in sync'.

I have tried to tinker with the rel_widths option in cowplot::plot_grid, but I am hoping for a more exact solution.

Rasmus Larsen
  • 5,721
  • 8
  • 47
  • 79

2 Answers2

3

I know this is not a direct answer to your question, but have you considered taking the same x-range for both plots and putting the legend where it fits?

library(cowplot)
library(tidyverse)    
wide_plot =  iris %>% 
  ggplot(aes(x = Sepal.Length, Sepal.Width, color = Species)) + 
  geom_point() + 
  theme(legend.position = "none") + 
  scale_x_continuous(limits = c(0,8), labels = scales::number_format(accuracy = 0.1))+
  scale_y_continuous( labels = scales::number_format(accuracy = 0.1)) 
narrow_plot =  iris %>% 
  ggplot(aes(x = Sepal.Width, Sepal.Length, color = Species)) + 
  geom_point()  + 
  theme(legend.position = c(0.9,0.7), legend.background = element_rect(size = 30)) + 
  scale_x_continuous(limits = c(0,8), labels = scales::number_format(accuracy = 0.1))+
  scale_y_continuous( labels = scales::number_format(accuracy = 0.1)) 

legend = cowplot::get_legend(ggplot(iris,aes(x = Sepal.Length, Sepal.Width, color = Species)) +  geom_point())

plot_grid(narrow_plot, wide_plot, nrow = 2) 

enter image description here

otwtm
  • 1,779
  • 1
  • 16
  • 27
2

You could adjust the margins and axis scales to allow the plots to line up:

wide_plot =  iris %>% 
    ggplot(aes(x = Sepal.Length, Sepal.Width, color = Species)) + 
      geom_point() + 
      theme(legend.position = "none", 
            plot.margin = unit(c(5.5, 140, 5.5, 0), "pt")) +
      scale_y_continuous(limits = c(1, 5)) +
      scale_x_continuous(limits = c(0, 8))

enter image description here

Allan Cameron
  • 147,086
  • 7
  • 49
  • 87
  • 1
    check out Z.Lins answer https://stackoverflow.com/questions/57392541/extend-axis-limits-without-plotting-in-order-to-align-two-plots-by-x-unit – tjebo May 12 '20 at 11:55
  • 1
    Thanks @Tjebo. I considered a similar approach here, but life's too short... – Allan Cameron May 12 '20 at 12:02