firmo23
firmo23

Reputation: 8404

Arrange ggplots and use a commom legend for them

Below I create 6 ggplots and my goal is to display them arranged like below-First column for 3 plots,2nd column for the rest of the 3 plots and one column for their shared legend in the 1st row.Below the legend is making my second plot small:

enter image description here

I tried to use the method for Legends found here with:

library(ggplot2) 
library(grid)
library(gridExtra) 

my_hist1 <- ggplot(diamonds, aes(clarity, fill = cut)) + 
  geom_bar() +theme(legend.position = "none")
my_hist2 <- ggplot(diamonds, aes(clarity, fill = cut)) + 
  geom_bar() +theme(legend.position = "none")
my_hist3 <- ggplot(diamonds, aes(clarity, fill = cut)) + 
  geom_bar() 
my_hist4 <- ggplot(diamonds, aes(clarity, fill = cut)) + 
  geom_bar() +theme(legend.position = "none")
my_hist5 <- ggplot(diamonds, aes(clarity, fill = cut)) + 
  geom_bar() +theme(legend.position = "none")
my_hist6 <- ggplot(diamonds, aes(clarity, fill = cut)) + 
  geom_bar() 






grid_arrange_shared_legend <-
  function(...,
           ncol = length(list(...)),
           nrow = 1,
           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"))
    gl <- c(gl, ncol = ncol, nrow = nrow)

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

    grid.newpage()
    grid.draw(combined)

    # return gtable invisibly
    invisible(combined)

  }

grid_arrange_shared_legend(my_hist1,my_hist2,my_hist3,my_hist4,my_hist5,my_hist6)

but I get everything in a row and the common legend at the bottom like:

enter image description here

Upvotes: 0

Views: 40

Answers (1)

phiggins
phiggins

Reputation: 248

I think you will like the patchwork package, which can arrange your plots as

((my_hist1 + my_hist2)/
(my_hist3 + my_hist4)/
(my_hist5 + my_hist6)) + 
plot_layout(guides = 'collect')

Detailed layout vignette for patchwork at: https://patchwork.data-imaginist.com/articles/guides/layout.html

Upvotes: 1

Related Questions