ggplot2 : printing multiple plots in one page with a loop

Matilde picture Matilde · Feb 16, 2015 · Viewed 8.1k times · Source

I have several subjects for which I need to generate a plot, as I have many subjects I'd like to have several plots in one page rather than one figure for subject. Here it is what I have done so far:

Read txt file with subjects name

subjs <- scan ("ListSubjs.txt", what = "")

Create a list to hold plot objects

pltList <- list()

for(s in 1:length(subjs))
{ 

  setwd(file.path("C:/Users/", subjs[[s]])) #load subj directory
  ifile=paste("Co","data.txt",sep="",collapse=NULL) #Read subj file
  dat = read.table(ifile)
  dat <- unlist(dat, use.names = FALSE) #make dat usable for ggplot2
  df <- data.frame(dat)

  pltList[[s]]<- print(ggplot( df, aes(x=dat)) +  #save each plot with unique name  
    geom_histogram(binwidth=.01, colour="cyan", fill="cyan") +
    geom_vline(aes(xintercept=0),   # Ignore NA values for mean
               color="red", linetype="dashed", size=1)+
   xlab(paste("Co_data", subjs[[s]] , sep=" ",collapse=NULL)))

}

At this point I can display the single plots for example by

print (pltList[1]) #will print first plot
print(pltList[2]) # will print second plot

I d like to have a solution by which several plots are displayed in the same page, I 've tried something along the lines of previous posts but I don't manage to make it work

for example:

for (p in seq(length(pltList))) {
  do.call("grid.arrange", pltList[[p]])  
}

gives me the following error

Error in arrangeGrob(..., as.table = as.table, clip = clip, main = main, : input must be grobs!

I can use more basic graphing features, but I d like to achieve this by using ggplot. Many thanks for consideration Matilde

Answer

baptiste picture baptiste · Jul 25, 2015

Your error comes from indexing a list with [[:

consider

pl = list(qplot(1,1), qplot(2,2))

pl[[1]] returns the first plot, but do.call expects a list of arguments. You could do it with, do.call(grid.arrange, pl[1]) (no error), but that's probably not what you want (it arranges one plot on the page, there's little point in doing that). Presumably you wanted all plots,

grid.arrange(grobs = pl)

or, equivalently,

do.call(grid.arrange, pl)

If you want a selection of this list, use [,

grid.arrange(grobs = pl[1:2])
do.call(grid.arrange, pl[1:2])

Further parameters can be passed trivially with the first syntax; with do.call care must be taken to make sure the list is in the correct form,

grid.arrange(grobs = pl[1:2], ncol=3, top=textGrob("title"))
do.call(grid.arrange, c(pl[1:2], list(ncol=3, top=textGrob("title"))))