Search code examples
rlayoutplotggplot2grid-layout

Layout of plots with a unique legend using ggplot


I was trying to create a layout with plots sharing the same legend. The legend is on the top of the first plot, however, the next plot has a different scale. How can I solve this?

library(ggplot2)
library(gridExtra)

grid.arrange(

ggplot(mpg, aes(displ, cty)) + 
  geom_point(aes(shape = "Data")) +
  stat_smooth(aes(linetype = "Regression"), method = "lm", 
              formula = y ~ x, se = FALSE, colour = 1, size = 0.5) +
  scale_shape_manual(values = 1) +
  labs(shape = "", linetype = "") +
  theme_classic() + 
  theme(panel.border = element_rect(colour = "black", fill=NA, size = 0.5),
        aspect.ratio = 1, axis.text = element_text(colour = 1, size = 10),
        legend.position = "top")
,
ggplot(mpg, aes(displ, cty)) + 
  geom_point(shape = 1) +
  stat_smooth(method = "lm", 
              formula = y ~ x, se = FALSE, colour = 1, size = 0.5) +
  theme_classic() + 
  theme(panel.border = element_rect(colour = "black", fill=NA, size = 0.5),
        aspect.ratio = 1, axis.text = element_text(colour = 1, size = 10))
)

IMAGE 1


Solution

  • I don't know how to use grid.arrange, but here's a solution using my cowplot package. The idea is to separate the legend out from the plot and then put the three elements into one column. A similar approach would work with grid.arrange, I assume.

    library(cowplot)
    
    p1 <- ggplot(mpg, aes(displ, cty)) + 
      geom_point(aes(shape = "Data")) +
      stat_smooth(aes(linetype = "Regression"), method = "lm", 
                  formula = y ~ x, se = FALSE, colour = 1, size = 0.5) +
      scale_shape_manual(values = 1) +
      labs(shape = "", linetype = "") +
      theme_classic() + 
      theme(panel.border = element_rect(colour = "black", fill=NA, size = 0.5),
            aspect.ratio = 1, axis.text = element_text(colour = 1, size = 10),
            legend.position = "top")
    
    p2 <- ggplot(mpg, aes(displ, cty)) + 
      geom_point(shape = 1) +
      stat_smooth(method = "lm", 
                  formula = y ~ x, se = FALSE, colour = 1, size = 0.5) +
      theme_classic() + 
      theme(panel.border = element_rect(colour = "black", fill=NA, size = 0.5),
            aspect.ratio = 1, axis.text = element_text(colour = 1, size = 10))
    
    legend <- get_legend(p1)
    plot_grid(legend, p1 + theme(legend.position = "none"), p2,
              ncol=1, rel_heights = c(0.1, 1, 1))
    

    enter image description here