如何将绘图附加到现有的 pdf 文件
Posted
技术标签:
【中文标题】如何将绘图附加到现有的 pdf 文件【英文标题】:How to append a plot to an existing pdf file 【发布时间】:2012-10-27 17:43:44 【问题描述】:我想在dev.off()
被调用后很久就将绘图附加到现有的 pdf 中*。在阅读了pdf()
帮助文件并阅读了问答here 和here 之后,我很确定它不能在R 中完成。但是,也许你们中的一些更聪明的人有一个解决方案,我没找到。
pdf("Append to me.%03d.pdf",onefile=T)
plot(1:10,10:1) #First plot (page 1)
dev.off()
pdf("Append to me.%03d.pdf",onefile=T)
plot(1:10,rep(5,10)) #Want this one on page 2
dev.off()
*这不是上面链接的问题的重复,因为我想在 pdf 设备关闭之后附加到 pdf 文件。
【问题讨论】:
也许这个Tyler Rinker's video 对你有帮助。这不是 R 答案,但很有趣。 您使用的是什么操作系统?您可以通过命令管道输出以将 pdf 流与现有 PDF 合并。 +1append.pdf
函数会很方便。
@Jilber。这是一个很好的问题,我应该尝试在我原来的问题中解决它。我正在校准一个模拟,其中运行大约需要 1 小时,整个校准过程可能需要一周或更长时间。在每次运行结束时,我想保存一个可以与过去运行比较的历史图。如果我想在模拟运行期间生成其他图,我认为将设备保持打开一周以上是不可行的。最终,我想并行执行一些运行并将输出合并到一个 pdf 文件中。
参见here Anandas 的第二条评论,他为多个操作系统提供了 R 解决方案。
【参考方案1】:
您可以使用recordPlot
将每个绘图存储在list
中,然后将它们全部写入一个pdf 文件,最后使用replayPlot
。这是一个例子:
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()
【讨论】:
很好的建议,我不知道recordPlot
。刚刚做了一些快速测试,看起来它会做得很好。谢谢!【参考方案2】:
如果您愿意安装小型、免费、独立于平台的 pdftk 实用程序,您可以使用 R 的系统调用将所有图形拼接在一起:
## 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"
【讨论】:
@josh-obrien 整洁!我也会把这个收起来以备将来使用。 喜欢这个解决方案【参考方案3】:这太骇人听闻了,可能掩盖了我有限的 UNIX shell fu,但它适用于安装了 pdfjam package 的 Fedora 17 机器(不是 R 包,而是来自 YUM 存储库)
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()
R 中的输出是:
> 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
基本上,如果pdfjoin
是唯一的输入文件,pdfjoin
将从stdin
获取输入,因此我将pdf()
的输出通过管道传输到pdfjoin
程序并使用--outfile
参数指定输出文件。然后使用&&
将原始pdf1.pdf
与刚刚创建的pdf2.pdf
连接起来,指定输出PDF为pdf1.pdf
,即原始PDF的名称。
【讨论】:
我要补充一点,写一个临时的pdf文件可能会更容易,然后使用system()
直接调用pdfjoin
来合并PDF然后删除临时的,但上面确实工作。
哇!你的 UNIX shell fu 比我的强得多。我要把它藏起来,以备将来使用。在那之前,我认为 mplourde 的解决方案将立即满足我的需求。【参考方案4】:
我最近发现了这部出色的作品(不是试图声称它是我自己的)
https://jonkimanalyze.wordpress.com/2014/07/24/r-compile-png-files-into-pdf/
这并不是 OP 所要求的,但我喜欢它的原因是我经常有非常密集的散点图和其他对 pdf 中的窗口大小调整等反应不佳的图。但是我需要产生多页输出。因此,如果绘图是数据密集型的,我会将它们渲染为 .png,然后使用上述函数在最后重新组合。
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)
【讨论】:
以上是关于如何将绘图附加到现有的 pdf 文件的主要内容,如果未能解决你的问题,请参考以下文章
如何将 Excel 转换为 JSON 并将其附加到现有的 JSON 文件?
如何使用 fast-csv npm 将新行或新行的数据(新行)附加到现有的 csv 文件
使用 Groovy 将 json 附加到现有的 json 文件中