5

I would like to control the layout when plotting a series of ggplots that I have stored in a list (generated automatically elsewhere).

I can plot series of plots as below.

library(ggplot2)
library(grid)
library(gridExtra)
p1 <- ggplot(mtcars, (aes(x=mpg, fill=as.factor(1)))) + geom_density() +  
                      scale_fill_manual(values="red") 
p2 <- ggplot(mtcars, (aes(x=mpg, fill=as.factor(1)))) + geom_density() +  
                      scale_fill_manual(values="orange") 
p3 <- ggplot(mtcars, (aes(x=mpg, fill=as.factor(1)))) + geom_density() +  
                      scale_fill_manual(values="yellow") 
p4 <- ggplot(mtcars, (aes(x=mpg, fill=as.factor(1)))) + geom_density() +  
                      scale_fill_manual(values="green") 
grid.arrange(p1, p2, p3, p4)

grid.arrange basic

I can then change their layout, as indicated here.

grid.arrange(p1, p2, p3, p4, layout_matrix=cbind(c(1,2), c(3,4)))

grid.arrange new layout

I can also plot a series of plots if they are stored in a list, as indicated here.

myplotslist <- list(p1, p2, p3, p4)
do.call(grid.arrange, c(myplotslist, ncol=2))

enter image description here

But if I try to change the layout using layout_matrix, I get an error (and some warnings).

do.call(grid.arrange, c(myplotslist, ncol=2, layout_matrix=cbind(c(1,2), c(3,4))))

Error in gList(list(grobs = list(list(x = 0.5, y = 0.5, width = 1, height = 1,  : 
  only 'grobs' allowed in "gList"
In addition: Warning messages:
1: In grob$wrapvp <- vp : Coercing LHS to a list
2: In grob$wrapvp <- vp : Coercing LHS to a list
3: In grob$wrapvp <- vp : Coercing LHS to a list
4: In grob$wrapvp <- vp : Coercing LHS to a list

I have tried coercing the plot objects to grobs, but encounter the same error.

myplotslist2 <- list(ggplotGrob(p1), ggplotGrob(p2), ggplotGrob(p3), ggplotGrob(p4))

I am using R 3.2.1, ggplot2 2.0.0, grid 3.2.1, and gridExtra 2.0.0, and would be extremely grateful for suggestions.

1
  • 1
    grid.arrange(p1, p2, p3, p4, ncol=2, layout_matrix=cbind(c(1,2), c(3,4))) Commented Jan 15, 2016 at 0:39

2 Answers 2

4

The arguments to the function you pass to do.call are really supposed to be a list. From ?do.call:

args a list of arguments to the function call. The names attribute of args gives the argument names.

The errors are telling you that your other arguments are getting passed to the grobs argument of grid.arrange. To stop that, put it in a list (c flattens too much here) and specify the grobs argument name for myplotslist:

do.call(grid.arrange, list(grobs = myplotslist, ncol=2, layout_matrix=cbind(c(1,2), c(3,4))))

...or you can ditch do.call entirely (h/t Baptiste):

grid.arrange(grobs = myplotslist, ncol=2, layout_matrix=cbind(c(1,2), c(3,4)))
Sign up to request clarification or add additional context in comments.

Comments

2

Not so sure why but this seems to work:

do.call(grid.arrange, c(myplotslist, ncol=2, layout_matrix=list(cbind(c(1,2), c(3,4)))))

1 Comment

c flattens the matrix. See the difference between c(cbind(c(1,2), c(3,4))) (1 2 3 4) and list(cbind(c(1,2), c(3,4))) (a matrix in a list).

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.