Search code examples
rggplot2gridextracowplot

Using grid.arrange with a list and extra arguments


It's the same question than this one : How do I arrange a variable list of plots using grid.arrange?, but with extra arguments, for example a legend.

Here is a toy example.

Here is the data:

Country = c("France", "Italy", "Peru", "Canada", "Brazill", "Spain", "Macedonia", "Austria")
Diet = c("carnivore", "homnivore", "vegtarian", "vegan")

n = 1000

data1 = data.frame("Country" = sample(Country, n, replace = TRUE),
              "Diet" = sample(Diet, n, replace = TRUE),
              "X" = sample(c(1 : 20), n, replace = TRUE),
              "Y" = sample(rnorm(n))) 

Here is an intermediate plot to make a legend:

plot = ggplot(data1, aes(x = Diet, fill = Diet)) + geom_histogram(stat = "count") + theme(legend.position = "bottom")

plot

legend <- cowplot::get_legend(plot)

Here is a list of plot I will arrange with grid.arrange:

Countries = data1$Country %>% unique

n = length(Countries)

l = lapply(c(1 : n), function(x) ggplot(data1 %>% filter(Country == Countries[[x]]), aes(x = Diet, fill = Diet)) + geom_histogram(stat = "count"))

Here is the result I want:

grid.arrange(legend, l[[2]], l[[3]], ncol = 2, layout_matrix = rbind(c(2, 3), c(1, 1)))

Here is how I would like to write it (without writing l[[1]], l[[2]]; useful if I have many plots):

do.call("grid.arrange", c(legend, l[1 : 2], ncol = 2, layout_matrix = rbind(c(2, 3), c(1, 1))))

But it doesn't work.

However it works without the extra arguments:

do.call("grid.arrange", c(l[1 : 2], ncol = 2))

Solution

  • Your issue is how you combine lists. You are doing this:

    a <- list(1, 2)
    b <- list(list(3, 4), list(5, 6))
    c <- 7
    
    c(a, b, c)
    

    As a result, everything gets added to the a list.

    What you want is this:

    c(list(a), b, c)