Esme_
Esme_

Reputation: 1520

Displaying saved ggplots in a grid when saved in a matrix in r

I have created plots using a loop and saved them in a matrix (see my earlier question). I now want to arrange the plots in a grid using plot_grid or similar. Is there a simple way to call the matrix of saved plots? I want the resulting grid of plots to match the layout of the matrix.

library(ggplot2)
library(gridExtra)
library(cowplot)


# create and save the plots to the matrix
plt <- vector('list', 10)
plt <- matrix(plt, nrow = 5, ncol = 2)

it = 1
while (it < 5){
  myX = runif(10)
  myY = runif(10)
  df = data.frame(myX,myY)
  plt[[it, 1]] = ggplot(data = df, aes(myX, myY)) + 
    geom_point(size = 2, color = "blue")
  plt[[it, 2]] = ggplot(data = df, aes(myX, myY)) + 
    geom_point(size = 2, color = "red")
  it = it + 1
}  

# display the plots in a grid that matches the matrix format
a1<- plt[[1,1]]
b1 <-plt[[1,2]]

a2<- plt[[2,1]]
b2 <-plt[[2,2]]

plot_grid(a1, b1, a2, b2, ncol = 2)

What I have above works, but I have had to assign each of the elements of the matrix to a variable, and then manually call all the variables in order in the plot_grid command. I am trying to find a way to avoid this. I have just showed a grid of 4 here - I have many more plots in my real problem.

I have tried using plot_grid(plt, ncol = 2), which gives the error "Cannot convert object of class matrixarray into a grob." I have also tried mylist = c(plt[[1,1]], plt[[1,2]], plt[[2,1]], plt[[2,2]]) and plot_grid(mylist, ncol = 2) but get the same error.

I also tried to use do.call("grid.arrange", c(plt, ncol = 2)) based on this answer but could not get that working.

Upvotes: 1

Views: 498

Answers (2)

MrFlick
MrFlick

Reputation: 206242

Storing non-atomic objects inside of matrices can be very messy. So first, gather the plots you want in a normal list, then, when passing the list to plot_grid, be sure do to so via the plotlist= parameter

mylist = list(plt[[1,1]], plt[[1,2]], plt[[2,1]], plt[[2,2]])
plot_grid(plotlist=mylist, ncol=2)

If you wanted to plot all the values, then you would just need to transpose the list because the list is stored in column order but is plotted in row order by default

plot_grid(plotlist=t(plt), ncol=2)

The do.call would have worked if you had a plain list and not a matrix list. YOu could have a helper function to remove the matrix part from the list when trying to plot. For example

undim <- function(x) {dim(x) <- NULL; x}
do.call("plot_grid", c(undim(plt), ncol = 2))

But here the plotlist= parameter is definitely the better way to dg.

Upvotes: 3

stefan
stefan

Reputation: 124183

In line with @MrFlick I would suggest to store your plots in a list which could be easily passed to plot_grid via argument plotlist

library(ggplot2)
library(gridExtra)
library(cowplot)

it = 1
plt <- list()
while (it < 5){
  myX = runif(10)
  myY = runif(10)
  df = data.frame(myX,myY)
  p1 <- ggplot(data = df, aes(myX, myY)) + 
    geom_point(size = 2, color = "blue")
  p2 <- ggplot(data = df, aes(myX, myY)) + 
    geom_point(size = 2, color = "red")
  
  plt <- c(plt, list(p1, p2))
  it <- it + 1
}  

# display the plots in a grid that matches the matrix format
plot_grid(plotlist = plt, ncol = 2)

Upvotes: 1

Related Questions