One shared legend for a cowplot grid in R
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:
Kai Mayer
Updated on June 17, 2022Comments
-
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 packageggplot2
: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:
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 almost 8 yearsjust edited. ggplot2 for the graphs and cowplot for the grid
-
IRTFM almost 8 yearsYou 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 almost 7 yearsNote that there is now a
get_legend(p)
function incowplot
(listed in the vignette you link). -
atsyplenkov about 4 yearsOr you can take a look at a
patchwork
package patchwork.data-imaginist.com