Background of grid.arrange
Asked Answered
E

2

6

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

Eighth answered 12/1, 2016 at 22:56 Comment(2)
just add panel.background = element_rect(fill = "grey80")Increate
Thank you for your comment MLavoie but that would change the background of the plotting area and I am interested in changing the color outside the plots.Eighth
O
7

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

Osbert answered 14/1, 2016 at 10:5 Comment(4)
Perfect! This was the solution I needed. I will go with arrangeGrob() for consistency. I also added col = "grey80" to the gpar()-function to get rid of the black border.Eighth
Any ideas on how to remove that bordering?Verona
grid.draw(grobTree(rectGrob(gp=gpar(lwd = 0))))Verona
It's barely noticeable on this plot. Not surprised no one complained about it. But I applied this solution to another plot that has a bit more spacing making the edging very noticeable.Verona
P
3

I think you could take advantage of the ggdraw() function from the cowplot package as showed here.

In your case, you would just need to add plot.background = element_rect(fill="grey80", color = NA) in the theme() of each plot p1 and p2, stitch them together with your function grid_arrange_shared_legend() and then call ggdraw() on its output:

g <- grid_arrange_shared_legend(p1,p2)
g2 <- cowplot::ggdraw(g) + 
  # same plot.background should be in the theme of p1 and p2 as mentioned above
  theme(plot.background = element_rect(fill="grey80", color = NA))
plot(g2)

enter image description here

Pickpocket answered 25/11, 2018 at 20:37 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.