rggplot2patchwork

Only collect partial of legends with patchwork


I am trying to only "collect" partial of legends with patchwork, below is a minimal example.

library(patchwork)
library(ggplot2)

p1 <- ggplot(mtcars, aes(mpg, disp, color = factor(vs))) + geom_point()
p2 <- ggplot(mtcars, aes(mpg, hp, color = factor(cyl))) + geom_point() + theme(legend.position = "bottom")
p3 <- ggplot(mtcars, aes(mpg, qsec, color = wt)) + geom_point()


(p1 | p2)/(p3 | p3 | p3) + patchwork::plot_layout(guides="collect") & theme(legend.position = "bottom")

The expectation is to keep the legend of p2 still at the bottom of p2, and collect and position the rest of legends at the bottom.

Thanks in advance.


Solution

  • One option would be to wrap p2 in wrap_elements where I additionally removed the plot.margin around p2 to still align the plot with the other plots:

    library(patchwork)
    library(ggplot2)
    
    p1 <- ggplot(mtcars, aes(mpg, disp, color = factor(vs))) +
      geom_point()
    p2 <- ggplot(mtcars, aes(mpg, hp, color = factor(cyl))) +
      geom_point() +
      theme(legend.position = "bottom")
    p3 <- ggplot(mtcars, aes(mpg, qsec, color = wt)) +
      geom_point()
    
    
    (p1 | wrap_elements(
      p2 + theme(plot.margin = margin())
    )) / (p3 | p3 | p3) +
      patchwork::plot_layout(guides = "collect") &
      theme(legend.position = "bottom")