25

I have several ggplots as objects on my ls. I want to save them as separate files (although I would also be interested to know how to save them all under 1 big file). I have read this: question and question but I can't seem to adapt the code. I also tried to plot them all in one big file as suggested here but do get this error: Error in do.call("grid.arrange", plots2[[i]]) : second argument must be a list. There's something that I am missing in getting all the ggplots in one list.

This is what I've tried so far:

> ls() #List of objects on my ls. All the p* are my ggplots that I want to save.
[1] "all"     "dat"     "dat2"    "dat3"    "data"    "dlook"   "dlook2"  "dlook3"  "i"       "look2"   "mdfx"   
[12] "objects" "order"   "p"       "p1"      "p10"     "p11"     "p12"     "p13"     "p14"     "p15"     "p16"    
[23] "p17"     "p18"     "p19"     "p2"      "p3"      "p4"      "p5"      "p6"      "p7"      "p8"      "p9"    

> objects<-ls()
> plot<-objects[14:30]
> plots
 [1] "p1"  "p10" "p11" "p12" "p13" "p14" "p15" "p16" "p17" "p18" "p19" "p2"  "p3"  "p4"  "p5"  "p6"  "p7"  "p8"  "p9" 

> class(plots)
[1] "character"

plots2<-as.list(plots)#Transform into a list. 

library(gridExtra) #Code suggested to create one pdf file.
pdf("test.pdf", onefile = TRUE)
for (i in seq(length(plots2))) {
  do.call("grid.arrange", plots2[[i]])  
}
dev.off()
Community
  • 1
  • 1
GodinA
  • 1,053
  • 3
  • 17
  • 27
  • Your link to the second question points to the same as the first. Also, are you trying to print one plot per page of a pdf, or arrange them on one page together? – MattLBeck Dec 10 '13 at 17:10
  • Oups sorry about that will fix this. I would like to know how to do both options 1) separate pdfs and 2) all in one big pdf, one plot per page. – GodinA Dec 10 '13 at 17:11
  • 1
    At the point you're at, you probably want `mget` (also note that `ls` will let you use regex to find items). But it would probably have been simpler (and cleaner) to put all the plots in a pre-allocated list in the first place. – joran Dec 10 '13 at 17:15
  • @joran can you show me how do to make a list & assign my plots? Or recommend any links/readings on how to do so? – GodinA Dec 10 '13 at 17:25
  • @GodinA Once you've read about `mget` and tried that out, you'll need to drop the for loop entirely. The point of `do.call` is that you hand it the function `grid.arrange` and the entire list of ggplot objects and it does the rest. – joran Dec 10 '13 at 17:29
  • @joran, I'd rather learn your suggested simpler & cleaner way to do it i.e., creating a list at the forefront. Will keep looking. – GodinA Dec 10 '13 at 17:41

4 Answers4

59

It's best to have your plots in a list

l = mget(plots)

Then you can simply print them page-by-page,

pdf("all.pdf")
invisible(lapply(l, print))
dev.off()

or save one plot per file,

invisible(mapply(ggsave, file=paste0("plot-", names(l), ".pdf"), plot=l))

or arrange them all in one page,

   # On Windows, need to specify device
    ggsave("arrange.pdf", arrangeGrob(grobs = l), device = "pdf")

or arrange them 2x2 in multiple pages,

  # need to specify device on Windows 
    ggsave("arrange2x2.pdf", marrangeGrob(grobs = l, nrow=2, ncol=2),
device = "pdf")

etc.

(untested)

NelsonGon
  • 13,015
  • 7
  • 27
  • 57
baptiste
  • 75,767
  • 19
  • 198
  • 294
  • 2
    This is very helpful - when I attempt with my own example, it produces a blank page. Any idea why this would happen? – EntryLevelR Apr 17 '17 at 18:45
12

Note that you don't have to work with lapply. Suppose you have a list containing all your plots:

MyPlots = list(plot1, plot2, plot3)

Just use:

pdf("all.pdf")
MyPlots
dev.off()
smillig
  • 5,073
  • 6
  • 36
  • 46
Rtist
  • 3,825
  • 2
  • 31
  • 40
6

If the plots p1, p10, etc. already exist, and you want them saved as p1.pdf, etc., then I think this should do it:

lapply(plots,function(x){ggsave(file=paste(x,"pdf",sep="."),get(x))})

ggsave(...) has a number of arguments for specifying the dimensions and format of the output file.

jlhoward
  • 58,004
  • 7
  • 97
  • 140
6

As an example fleshing out Joran's comment, and a supplement to Baptiste's answer, this is how you would initialize a list and store plots in a list up-front:

plots <- list()
plots[[1]] <- ggplot(...) # code for p1
plots[[2]] <- ggplot(...) # code for p2

## Depending on if your plots are scriptable, you could use a loop

for (i in 3:10) {
    plots[[i]] <- ggplot(...) # code for plot i
}

Then this list, plots, corresponds to l in baptiste's answer.

When using lists, single brackets, [, are used for sublists, where you have to use double brackets [[ to get the element of a list. For example, plots[[1]] will give you the ggplot object that is the first element of plots, but plots[1] will give you a length one list containing that first plot as an element. This may seem confusing at first, but it makes sense, especially if you just wanted to plot the first three plots, then you could use myplots[1:3] instead of l in any of baptiste's examples. (See ?"[" for more details.)

Whenever you catch yourself naming variables sequentially with numbers, e.g., x1, x2, x3, it's a good indication that you should be using a list instead.

Gregor Thomas
  • 136,190
  • 20
  • 167
  • 294