One shared legend for a cowplot grid in R

15,729

Solution 1

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))

Solution 2

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 = T)

See example with mtcars dataset:

library(tidyverse)
library(ggpubr)

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

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

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

Voila:

enter image description here

Share:
15,729
Kai Mayer
Author by

Kai Mayer

Updated on June 17, 2022

Comments

  • Kai Mayer
    Kai Mayer almost 2 years

    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.

    • Kai Mayer
      Kai Mayer almost 8 years
      just edited. ggplot2 for the graphs and cowplot for the grid
    • IRTFM
      IRTFM almost 8 years
      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.
  • Michael Schubert
    Michael Schubert almost 7 years
    Note that there is now a get_legend(p) function in cowplot (listed in the vignette you link).
  • atsyplenkov
    atsyplenkov about 4 years
    Or you can take a look at a patchwork package patchwork.data-imaginist.com