One shared legend for a cowplot grid in R
Asked Answered
W

2

20

I just built a grid with package cowplot (to label the plots from A-D). The plots are made with package ggplot2:

pfour<-ggplot(four, aes(x=Concentration, y=Percentage, fill=Phenotype)) + 
 geom_bar(stat='identity',color='black') +
 scale_fill_grey(start = .4, end = .9) + 
 theme_bw()+ylab("Distribution") + 
 xlab("Contentration [mg/ml]") + 
 ggtitle("96 hpf") +
 theme(legend.title = element_text(colour="black", size=10, face="bold")) +
 theme(legend.background = element_rect(fill="white",
                                        size=0.5, linetype="solid", 
                                        colour ="black")) +
 scale_x_discrete(limits=c('uninjected','control','0.002', '0.02', '0.2'),
                  labels=c('uninjected\n(n=251)',
                           'control\n(n=248)', 
                           '0.002\n(n=205)', 
                           '0.02\n(n=222)', 
                           '0.2\n(n=203)'))

the data looks like that (4 different tables with slightly different percentages but the same principle):

Concentration,Percentage,Phenotype
uninjected,0.996015936,0
uninjected,0,1
uninjected,0.003984064,2
uninjected,0,3
uninjected,0,4
control,0.995967742,0
control,0.004032258,1
control,0,2
control,0,3
control,0,4
0.002,0.985365854,0
0.002,0.004878049,1
0.002,0.004878049,2
0.002,0,3
0.002,0.004878049,4
0.02,0.981981982,0
0.02,0.004504505,1
0.02,0.004504505,2
0.02,0.004504505,3
0.02,0.004504505,4
0.2,0.985221675,0
0.2,0.004926108,1
0.2,0,2

and it looks like that:

plot

the code for that is :

plot_grid(ponezoom, ptwozoom,pthreezoom,pfourzoom, align='h', labels=c('A', 'B','C','D'))

Now I was wondering if it is possible to get one single shared legend for all four plots as it steals a lot of plotspace to have it 4 times. I appreciate any help.

Wry answered 19/5, 2016 at 23:34 Comment(2)
just edited. ggplot2 for the graphs and cowplot for the gridWry
You should clarify whether two legends at the bottom of each column would be satisfactory or whether it needs to be a single legend. You should also post some data.Notional
H
22

There is a vignette that shows how to do this.

The approach is to build your plots with the legend hidden theme(legend.position="none"). Then extract the legend grob from one of those objects.

grobs <- ggplotGrob(pfour)$grobs
legend <- grobs[[which(sapply(grobs, function(x) x$name) == "guide-box")]]

Then plot the legend as a seperate 'plot'. To have the legend at to the right you might do:

# build grid without legends
pgrid <- plot_grid(pone, ptwo, pthree, pfour, ncol = 2)
# add legend
p <- plot_grid(pgrid, legend, ncol = 2, rel_widths = c(1, .1))
Hazaki answered 20/5, 2016 at 11:33 Comment(1)
Note that there is now a get_legend(p) function in cowplot (listed in the vignette you link).Gerhardine
D
8

You can use ggarrange function from ggpubr package. It has a logical argument common.legend. You just need to set it TRUE. In your case a code chunk will be:

library(ggpubr)

ggarrange(
  ponezoom, ptwozoom, pthreezoom, pfourzoom,
  align = "h", labels = c("A", "B", "C", "D"),
  common.legend = TRUE
)

See example with mtcars dataset:

library(tidyverse)
library(ggpubr)

# Create first plot
plot1 <-
  mtcars %>%
  ggplot(aes(mpg, hp, color = factor(cyl))) +
  geom_point(size = 2) +
  theme_minimal()

# Create second plot
plot2 <-
  mtcars %>%
  ggplot(aes(disp, drat, color = factor(cyl))) +
  geom_point(size = 2) +
  theme_minimal()

# Create grid
ggpubr::ggarrange(
  plot1, plot2, # list of plots
  labels = "AUTO", # labels
  common.legend = TRUE, # COMMON LEGEND
  legend = "bottom", # legend position
  align = "hv", # Align them both, horizontal and vertical
  nrow = 2 # number of rows
)

Voila:

ggpubr common legend example

UPDATE

While the solution with ggpubr still works, one may find patchwork package more flexible. For example, to reproduce the above created figure with patchwork you can use the following code:

library(patchwork)

plot1 / plot2 +
  patchwork::plot_layout(
    guides = "collect",
    nrow = 2
  ) +
  patchwork::plot_annotation(
    tag_levels = "A"
  ) &
  theme(legend.position = "bottom", legend.direction = "horizontal")

patchwork common legend example

Dallasdalli answered 13/2, 2020 at 9:19 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.