将多个ggplot2图保存为列表中的R对象,并在网格

时间:2015-08-11 16:59:18

标签: r ggplot2 plot r-grid

我想在大型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

2 个答案:

答案 0 :(得分:0)

我可以想到两个解决方案。

<强> 1。如果你的目标只是将图表列表保存为R对象,我建议:

    saveRDS(object = pltlist, file = "file_path")

这样,当您希望在这些图表中重新加载时,您可以使用readRDS()。然后,您可以将它们放在cowplotgridarrange中。此命令适用于所有列表和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))
    }
  }
}

结果:

enter image description here