Search code examples
rggplot2r-grid

Background of grid.arrange


I have made a plot like the one described by the code below resulting in the posted image. I can not figure out how to set the entire background to the same "grey80"-color I have used when defining the subplots. Ie. I want to color the white areas between the plots and on the sides of the legend in the same color. Is this possible to achieve, perhaps with some fancy gridgrob-magic?

This question is similar to change the background color of grid.arrange output but I would like a solution without using the png() function, if possible

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

p1 <- ggplot(iris, aes(x = Sepal.Length, y = Sepal.Width,
                       colour = Species)) + 
  ggtitle('Sepal') + 
  geom_point() + theme_bw() + 
  theme(rect = element_rect(fill = 'grey80'))


p2 <- ggplot(iris, aes(x = Petal.Length, y = Petal.Width,
                       colour = Species)) + 
  ggtitle('Petal') + 
  geom_point() + theme_bw() + 
  theme(rect = element_rect(fill = 'grey80'))

grid_arrange_shared_legend <- function(...) {
  plots <- list(...)
  g <- ggplotGrob(plots[[1]] + theme(legend.position = "bottom"))$grobs
  legend <- g[[which(sapply(g, function(x) x$name) == "guide-box")]]
  lheight <- sum(legend$height)
  grid.arrange(
    do.call(arrangeGrob, lapply(plots, function(x)
      x + theme(legend.position="none"))),
    legend,
    ncol = 1,
    heights = unit.c(unit(1, "npc") - lheight, lheight))
}

grid_arrange_shared_legend(p1,p2)

Grid arrange plot


Solution

  • upgrade comment

    You can do this by adding a grey background to the graphics window and then adding the plots on top. As your legend function uses grid.arrange this generates a newpage; so either add newpage=FALSE or change to arrangeGrob to your function.

    Your example

    library(ggplot2)
    library(gridExtra)
    library(ggthemes)
    library(grid)
    
    p1 <- ggplot(iris, aes(x = Sepal.Length, y = Sepal.Width, colour = Species)) + 
             ggtitle('Sepal') + 
             geom_point() + theme_bw() + 
             # by adding colour=grey removes the white border of the plot and
             # so removes the lines between the plots
             # add panel.background = element_rect(fill = "grey80") 
             # if you want the plot panel grey aswell
             theme(plot.background=element_rect(fill="grey80", colour="grey80"),
                   rect = element_rect(fill = 'grey80'))
    
    p2 <- ggplot(iris, aes(x = Petal.Length, y = Petal.Width, colour = Species)) + 
             ggtitle('Petal') + 
             geom_point() + theme_bw() + 
             theme(plot.background=element_rect(fill="grey80", colour="grey80"),
                   rect = element_rect(fill = 'grey80'))
    

    Tweal your function

    # Change grid.arrange to arrangeGrob
    grid_arrange_shared_legend <- function(...) {
      plots <- list(...)
      g <- ggplotGrob(plots[[1]] + theme(legend.position = "bottom"))$grobs
      legend <- g[[which(sapply(g, function(x) x$name) == "guide-box")]]
      lheight <- sum(legend$height)
      arrangeGrob( # change here
        do.call(arrangeGrob, lapply(plots, function(x)
                                       x + theme(legend.position="none"))),
        legend,
        ncol = 1,
        heights = unit.c(unit(1, "npc") - lheight, lheight))
    }
    

    Plot

    grid.draw(grobTree(rectGrob(gp=gpar(fill="grey80", lwd=0)), 
                       grid_arrange_shared_legend(p1,p2)))
    

    Which gives

    enter image description here