I want to append a plot to an existing pdf long after dev.off() has been called*. After reading the pdf() help file and after reading the Q &
This is horribly hacky and probably belies my limited UNIX shell fu, but it works for me on a Fedora 17 box with the pdfjam package installed (not an R package, but from the YUM repos)
pdf("pdf1.pdf")
plot(1:10)
dev.off()
pdf("| pdfjoin --outfile \"pdf2.pdf\" && pdfjoin pdf1.pdf pdf2.pdf --outfile pdf1.pdf && rm pdf2.pdf")
plot(10:1)
dev.off()
The output in R is:
> pdf("| pdfjoin --outfile \"pdf2.pdf\" && pdfjoin pdf1.pdf pdf2.pdf --outfile pdf1.pdf && rm pdf2.pdf")## && pdfunite joined.pdf tmp.pdf joined.pdf && rm tmp.pdf")
> plot(10:1)
> dev.off()
----
pdfjam: This is pdfjam version 2.08.
pdfjam: Reading any site-wide or user-specific defaults...
(none found)
pdfjam: No PDF/JPG/PNG source specified: input is from stdin.
pdfjam: Effective call for this run of pdfjam:
/usr/bin/pdfjam --fitpaper 'true' --rotateoversize 'true' --suffix joined --outfile pdf2.pdf -- /dev/stdin -
pdfjam: Calling pdflatex...
pdfjam: Finished. Output was to 'pdf2.pdf'.
----
pdfjam: This is pdfjam version 2.08.
pdfjam: Reading any site-wide or user-specific defaults...
(none found)
pdfjam: Effective call for this run of pdfjam:
/usr/bin/pdfjam --fitpaper 'true' --rotateoversize 'true' --suffix joined --outfile pdf1.pdf -- pdf1.pdf - pdf2.pdf -
pdfjam: Calling pdflatex...
pdfjam: Finished. Output was to 'pdf1.pdf'.
null device
1
Basically, pdfjoin will take input from stdin if it is the only input file so I pipe the output from pdf() to the pdfjoin program and specify the output file using the --outfile argument. Then using && is join the original pdf1.pdf with the pdf2.pdf just created, specifying that the output PDF is pdf1.pdf, the name of the original PDF.
You could use recordPlot to store each plot in a list, then write them all to a pdf file at the end with replayPlot. Here's an example:
num.plots <- 5
my.plots <- vector(num.plots, mode='list')
for (i in 1:num.plots) {
plot(i)
my.plots[[i]] <- recordPlot()
}
graphics.off()
pdf('myplots.pdf', onefile=TRUE)
for (my.plot in my.plots) {
replayPlot(my.plot)
}
graphics.off()
I found this excellent work recently (not attempting to claim it as my own)
https://jonkimanalyze.wordpress.com/2014/07/24/r-compile-png-files-into-pdf/
It's not quite what the OP was asking for, but the reason I like it is that I often have quite dense scatterplots and other plots that don't respond particularly well to window resizing etc. within a pdf. However I need to produce multi page output. So if the plots are data-dense I render them as .pngs and then use the above function to recombine at the end.
merge.png.pdf <- function(pdfFile, pngFiles, deletePngFiles=FALSE) {
pdf(pdfFile)
n <- length(pngFiles)
for( i in 1:n) {
pngFile <- pngFiles[i]
pngRaster <- readPNG(pngFile)
grid.raster(pngRaster, width=unit(0.8, "npc"), height= unit(0.8, "npc"))
if (i < n) plot.new()
}
dev.off()
if (deletePngFiles) {
unlink(pngFiles)
}
}
If you are willing to install the small, free, platform-independent pdftk utililty, you could use a system call from R to have it stitch all of your figures together:
## A couple of example pdf docs
pdf("Append to me.1.pdf")
plot(1:10,10:1)
dev.off()
pdf("Append to me.2.pdf")
plot(1:10,rep(5,10))
dev.off()
## Collect the names of the figures to be glued together
ff <- dir(pattern="Append to me")
## The name of the pdf doc that will contain all the figures
outFileName <- "AllFigs.pdf"
## Make a system call to pdftk
system2(command = "pdftk",
args = c(shQuote(ff), "cat output", shQuote(outFileName)))
## The command above is equiv. to typing the following at the system command line
## pdftk "Append to me.1.pdf" "Append to me.2.pdf" cat output "AllFigs.pdf"