Skip to content

Share a legend between two ggplot2 graphs

baptiste edited this page May 24, 2016 · 8 revisions
Clone this wiki locally

Share a legend between multiple plots using grid.arrange

Goal: share a legend between multiple plots that do not also share axes

See this example at RPubs:sjackman/grid_arrange_shared_legend.

It is sometimes possible to obtain good results by creating a dummy faceting of the data as in Align-two-plots-on-a-page, but this technique is not entirely appropriate when the plots do not also share axes. For greater control, you can also use Grid to place the plots and the legends in an arbitrary layout.

  1. create four plots p1, p2, p3 and p4
  2. save the legend of p1 as a separate grob
  3. strip the legends from the plots
  4. draw the four plots and the legend below them

grid_arrange_shared_legend <- function(..., position = c("bottom", "right")) {

  plots <- list(...)
  position <- match.arg(position)
  g <- ggplotGrob(plots[[1]] + theme(legend.position=position))$grobs
  legend <- g[[which(sapply(g, function(x) x$name) == "guide-box")]]
  lheight <- sum(legend$height)
  lwidth <- sum(legend$width)
  gl <- lapply(plots, function(x) x + theme(legend.position="none"))

  combined <- switch(position,
                     "bottom" = arrangeGrob(, gl),
                                            ncol = 1,
                                            heights = unit.c(unit(1, "npc") - lheight, lheight)),
                     "right" = arrangeGrob(, gl),
                                           ncol = 2,
                                           widths = unit.c(unit(1, "npc") - lwidth, lwidth)))

dsamp <- diamonds[sample(nrow(diamonds), 1000), ]
p1 <- qplot(carat, price, data=dsamp, colour=clarity)
p2 <- qplot(cut, price, data=dsamp, colour=clarity)
p3 <- qplot(color, price, data=dsamp, colour=clarity)
p4 <- qplot(depth, price, data=dsamp, colour=clarity)
grid_arrange_shared_legend(p1, p2, p3, p4)
Something went wrong with that request. Please try again.