我想在大型for循环期间将多个图(使用ggplot2)保存到列表中。然后随后在网格中显示图像(使用grid.arrange)
我尝试了两个解决方案: 1将其存储在列表中,如下所示:
pltlist[["qplot"]] <- qplot
然而由于某种原因,这确实可以正确地保存情节。 所以我使用了第二个策略,即recordPlot() 这能够正确地保存绘图,但无法 在网格中使用它。
可再现的例子:
require(ggplot2);require(grid);require(gridExtra)
df <- data.frame(x = rnorm(100),y = rnorm(100))
histoplot <- ggplot(df, aes(x=x)) + geom_histogram(aes(y=..density..),binwidth=.1,colour="black", fill="white")
qplot <- qplot(sample = df$y, stat="qq")
pltlist <- list()
pltlist[["qplot"]] <- qplot
pltlist[["histoplot"]] <- histoplot
grid.arrange(pltlist[["qplot"]],pltlist[["histoplot"]], ncol=2)
上面的代码可以工作,但会生成错误的图表 在我的实际代码中
然后我尝试了recordPlot()
print(histoplot)
c1 <- recordPlot()
print(qplot)
c2 <- recordPlot()
我可以单独显示所有图表 但是grid.arrange会产生错误:
grid.arrange(replayPlot(c1),replayPlot(c2), ncol=2) # = Error
gList中的错误(list(wrapvp = list(x = 0.5,y = 0.5,width = 1,height = 1,: 只有&#39; grobs&#39;允许进入&#34; gList&#34;
在这个帖子中Saving grid.arrange() plot to file 他们讨论了一个利用arrangeGrob()代替
的解决方案arrangeGrob(c1, c1, ncol=2) # Error
vapply错误(x $ grobs,as.character,character(1)): 值必须是长度1, 但是FUN(X [[1]])结果是长度3
我被迫使用recordPlot()而不是保存到列表中,因为这在保存时不会产生与立即绘制时相同的图形,我很遗憾无法复制,对不起。
在我的实际代码中,我正在进行一个大的for循环,循环遍历几个变量,与每个变量建立关联并制作散点图,我将散点图命名为依赖于其重要级别。然后,我想在动态编织报告中重新显示网格中重要的图。
我知道我可以重新绘制for循环之后重要的绘图而不是保存它们(我在编织时也不能保存为png)。但是我想找到一种方法来动态地将绘图保存为R对象,然后在网格中重新绘制它们。
感谢阅读
&#34; R版本3.2.1&#34; Windows 7 64位 - RStudio - 版本0.99.652 附加基础包: [1] grid grDevices datasets utils graphics stats methods base
其他附件包: [1] gridExtra_2.0.0 ggplot2_1.0.1
答案 0 :(得分:0)
我可以想到两个解决方案。
<强> 1。如果你的目标只是将图表列表保存为R对象,我建议:
saveRDS(object = pltlist, file = "file_path")
这样,当您希望在这些图表中重新加载时,您可以使用readRDS()
。然后,您可以将它们放在cowplot
或gridarrange
中。此命令适用于所有列表和R对象。
这种方法的一个警告是,ggplot2的设置/标签是否依赖于环境中的事物(不是数据,而是像点大小,形状或着色的设置),而不是用于制作图形的ggplot2函数),在恢复依赖项之前,您的图形将不起作用。保存一些依赖项的一个原因是模块化脚本以生成图形。
另一个警告是性能:根据我的经验,我发现当你有大量的图形(100多个图形)时,读取数据并重新制作单个图形实际上比加载所有图形的RDS文件更快。
<强> 2。如果您的目标是保存每个图形的“图像”或“图片”(单个和/或多个图形为.png,.jpeg等),然后在R之外手动调整网格中的内容作为powerpoint或photoshop,我建议:
filenames <- c("Filename_1", "Filename_2") #actual file names you want...
lapply(seq_along(pltlist), function(i) {
ggsave(filename = filenames[i], plot = pltlist[[i]], ...) #use your settings here
})
我喜欢单个地块的设置:
lapply(seq_along(pltlist), function(i) ggsave(
plot = pltlist[[i]],
filename = paste0("plot_", i, "_", ".tiff"), #you can even paste in pltlist[[i]]$labels$title
device = "tiff", width=180, height=180, units="mm", dpi=300, compression = "lzw", #compression for tiff
path = paste0("../Blabla") #must be an existing directory.
))
如果你真的是关于网格安排的强迫症,你可能想要做手动方法,而你没有太多的东西来制作出版物。否则,当你执行grid.arrange时,你会想要做那里的所有规范(调整字体,增加轴标签大小,自定义颜色等),然后相应地调整宽度和高度。
答案 1 :(得分:0)
重新整理此帖子,以在其中添加multiplot,因为它恰好适合。
require(ggplot2)
mydd <- setNames( data.frame( matrix( rep(c("x","y","z"), each=10) ),
c(rnorm(10), rnorm(10), rnorm(10)) ), c("points", "data") )
# points data
# 1 x 0.733013658
# 2 x 0.218838717
# 3 x -0.008303382
# 4 x 2.225820069
# ...
p1 <- ggplot( mydd[mydd$point == "x",] ) + geom_line( aes( 1:10, data, col=points ) )
p2 <- ggplot( mydd[mydd$point == "y",] ) + geom_line( aes( 1:10, data, col=points ) )
p3 <- ggplot( mydd[mydd$point == "z",] ) + geom_line( aes( 1:10, data, col=points ) )
multiplot(p1,p2,p3, cols=1)
多重绘图:
multiplot <- function(..., plotlist=NULL, file, cols=1, layout=NULL) {
library(grid)
# Make a list from the ... arguments and plotlist
plots <- c(list(...), plotlist)
numPlots = length(plots)
# If layout is NULL, then use 'cols' to determine layout
if (is.null(layout)) {
# Make the panel
# ncol: Number of columns of plots
# nrow: Number of rows needed, calculated from # of cols
layout <- matrix(seq(1, cols * ceiling(numPlots/cols)),
ncol = cols, nrow = ceiling(numPlots/cols))
}
if (numPlots==1) {
print(plots[[1]])
} else {
# Set up the page
grid.newpage()
pushViewport(viewport(layout = grid.layout(nrow(layout), ncol(layout))))
# Make each plot, in the correct location
for (i in 1:numPlots) {
# Get the i,j matrix positions of the regions that contain this subplot
matchidx <- as.data.frame(which(layout == i, arr.ind = TRUE))
print(plots[[i]], vp = viewport(layout.pos.row = matchidx$row,
layout.pos.col = matchidx$col))
}
}
}
结果: