Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Background of grid.arrange

Tags:

r

ggplot2

r-grid

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

like image 809
Gabra Avatar asked Jan 12 '16 22:01

Gabra


People also ask

What is Grid Arrange function in R?

If layout parameters are ommitted altogether, grid. arrange() will calculate a default number of rows and columns to organise the plots. More complex layouts can be achieved by passing specific dimensions (widths or heights), or a layout matrix defining the position of each plot in a rectangular grid.

What does the gridExtra package allow you to do?

The gridExtra package provides useful extensions to the grid system, with an emphasis on higher-level functions to work with grid graphic objects, rather than the lower-level utilities in the grid package that are used to create and edit specific lower-level elements of a plot.

What is a Grob in Ggplot?

First off a grob is just short for “grid graphical object” from the low-level graphics package grid; Think of it as a set of instructions for create a graphical object (i.e. a plot). The graphics library underneath all of ggplot2's graphical elements are really composed of grob's because ggplot2 uses grid underneath.

How do you make a grid plot in R?

Creating a Grid of Plots To do this, you use the parameter value mfrow=c(x,y) where x is the number of rows that you wish to have in your plot and y is the number of columns. When you plot, R will place each plot, in order by row within the grid that you define using mfrow .


2 Answers

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

like image 90
user20650 Avatar answered Sep 19 '22 23:09

user20650


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

like image 38
Valentin Avatar answered Sep 18 '22 23:09

Valentin