6

Is it possible to have legend below 'main' title' and above plot titles using patchwork?

library(ggplot2)
library(patchwork)

p1 <- ggplot(mtcars, aes(disp, wt, color = factor(gear))) + 
    geom_point() + 
    labs(title = "first plot title")
p2 <- ggplot(mtcars, aes(drat, qsec, color = factor(gear))) + 
    geom_point() + 
    labs(title = "second plot title")

(p1+p2) + 
    plot_layout(guides = "collect") + 
    plot_annotation(title = "main title") & 
    theme(legend.position = "top")

enter image description here

zx8754
  • 52,746
  • 12
  • 114
  • 209
det
  • 5,013
  • 1
  • 8
  • 16

2 Answers2

4

Another way to address this issue is to use the guide_area function within patchwork. The guide area is used to collect all legends if you code it to do so. You can manipulate the guide area as if it is a plot.

In the example below I added a guide area, placed it in its own row at the top, and then made the relative heights 1:10 so that the guide area takes up less space.

There are many ways to manipulate a guide area and you may need to adjust the theme as desired to fit different situations.

p1 <- ggplot(mtcars, aes(disp, wt, color = factor(gear))) + 
  geom_point() + 
  labs(title = "first plot title")

p2 <- ggplot(mtcars, aes(drat, qsec, color = factor(gear))) + 
  geom_point() + 
  labs(title = "second plot title")

guide_area() + (p1+p2) + 
  plot_layout(guides = "collect", 
              nrow = 2, heights = c(1,10)) + 
  plot_annotation(title = "main title") & 
  theme(legend.position = "top")

enter image description here

wayne r
  • 110
  • 1
  • 5
3

A bit of a hack, extract the legend then plot it at the top:

# get the legend
myLegend <- cowplot::get_legend(p1 + theme(legend.position = "top"))

(cowplot::plot_grid(myLegend) / (p1 + p2)) + 
  plot_layout(heights = unit(c(1, 5), "cm")) +
  plot_annotation(title = "main title") &
  theme(legend.position = "none")

enter image description here

zx8754
  • 52,746
  • 12
  • 114
  • 209