【问题标题】:Printing multiple ggplots into a single pdf, multiple plots per page将多个ggplots打印到一个pdf中,每页多个图
【发布时间】:2012-08-27 09:17:53
【问题描述】:

我有一个列表,p,其中p 的每个元素都是 ggplot2 绘图对象的列表。

我想输出一个包含p 中所有图的单个 pdf,这样p[[1]] 中的图在第 1 页,p[[2]] 中的图在第 2 页,等等。我该怎么做?

这里有一些示例代码,可以为您提供我正在使用的数据结构 - 为无聊的情节道歉,我随机选择了变量。

require(ggplot2)
p <- list()

cuts <- unique(diamonds$cut)
for(i in 1:length(cuts)){
    p[[i]] <- list()
    dat <- subset(diamonds, cut==cuts[i])
    p[[i]][[1]] <- ggplot(dat, aes(price,table)) + geom_point() + 
        opts(title=cuts[i])
    p[[i]][[2]] <- ggplot(dat, aes(price,depth)) + geom_point() + 
        opts(title=cuts[i])
}

【问题讨论】:

  • 这是一个潜在的开始:require(gridExtra); do.call("grid.arrange",p[[i]])。这将在单个设备中绘制 p[[i]] 中的 ggplot 对象,并很好地排列它们。
  • 还可以查看 gridExtra 包。我认为这应该能让你大部分时间到达那里

标签: r ggplot2


【解决方案1】:

此方案与列表p中的列表长度是否不同无关。

library(gridExtra)

pdf("plots.pdf", onefile = TRUE)
for (i in seq(length(p))) {
  do.call("grid.arrange", p[[i]])  
}
dev.off()

由于onefile = TRUE,函数pdf 将所有按顺序出现的图形保存在同一个文件中(一个图形一页)。

【讨论】:

  • 对我来说,这会导致损坏的 PDF 无法打开。这些情节看起来很好。有什么建议吗?
  • opts() 在ggplot2_2.2.1R version 3.3.2 上对我不起作用。请改用+ ggtitle(cuts[i])
  • @half-pass,我遇到了同样的问题。在我的例子中,在 ggplot2 对象上做一个明确的print() 解决了这个问题(即将绘图保存到对象,然后打印它,对于循环的每次迭代)。
  • seq_along(p) 可以用来代替seq(length(p))
  • 对于其他遇到麻烦的人:请注意,此解决方案仅在 ggplot 对象在列表中时才有效。如果将它们作为单独的参数添加到 grid.arrange,您将在 pdf 中获得几页,只有最后一页是您想要的组合。
【解决方案2】:

这里是 Sven 解决方案的一个简单版本,适用于 R 初学者,否则他们会盲目地使用他们既不需要也不理解的 do.call 和嵌套列表。我有经验证据。 :)

library(ggplot2)
library(gridExtra)

pdf("plots.pdf", onefile = TRUE)
cuts <- unique(diamonds$cut)
for(i in 1:length(cuts)){
    dat <- subset(diamonds, cut==cuts[i])
    top.plot <- ggplot(dat, aes(price,table)) + geom_point() + 
        opts(title=cuts[i])
    bottom.plot <- ggplot(dat, aes(price,depth)) + geom_point() + 
        opts(title=cuts[i])
    grid.arrange(top.plot, bottom.plot)
}
dev.off()

【讨论】:

    【解决方案3】:

    这是使用 ggplot2::ggsave()gridExtra::marrangeGrob() 将 ggplot 对象列表导出到单个 pdf 文件的最优雅的解决方案。

    library(ggplot2)
    library(gridExtra)
    

    假设您使用lapply() 创建多个绘图

    p <- lapply(names(mtcars), function(x) {
      ggplot(mtcars, aes_string(x)) + 
        geom_histogram()
    })
    

    保存p地块列表:

    ggsave(
       filename = "plots.pdf", 
       plot = marrangeGrob(p, nrow=1, ncol=1), 
       width = 15, height = 9
    )
    

    【讨论】:

    • 这是否适用于 group_by() 函数?
    【解决方案4】:

    我尝试了其中的一些解决方案,但没有成功。我进行了更多研究,并找到了一个非常适合我的解决方案。它将我所有的图形保存在一个 pdf 文件中,每个图表在一页上。

    library(ggplot2)
    
    
    pdf("allplots.pdf",onefile = TRUE)
    for(i in glist){
       tplot <- ggplot(df, aes(x = as.factor(class), y = value))
       print(tplot)
    }
    dev.off()
    

    【讨论】:

      【解决方案5】:

      这是一种解决方案,但我不是特别喜欢它:

      ggsave("test.pdf", do.call("marrangeGrob", c(unlist(p,recursive=FALSE),nrow=2,ncol=1)))

      问题在于它依赖于每组中的地块数量相同。如果all(sapply(p, length) == 2) 为假,那么它就会中断。

      【讨论】:

        【解决方案6】:

        这是一个基于 Sven 方法的函数,包括 roxygen2 文档和示例。

        #' Save list of ggplot2 objects to single pdf
        #'
        #' @param list (list) List of ggplot2 objects.
        #' @param filename (chr) What to call the pdf.
        #'
        #' @return Invisible NULL.
        #' @export
        #'
        #' @examples
        #' #plot histogram of each numeric variable in iris
        #' list_iris = map(names(iris[-5]), ~ggplot(iris, aes_string(.)) + geom_histogram())
        #' #save to a single pdf
        #' GG_save_pdf(list_iris, "test.pdf")
        GG_save_pdf = function(list, filename) {
          #start pdf
          pdf(filename)
        
          #loop
          for (p in list) {
            print(p)
          }
        
          #end pdf
          dev.off()
        
          invisible(NULL)
        }
        

        【讨论】:

          【解决方案7】:

          使用ggpubr 包对我有用的解决方案(Github 上的包,安装代码:devtools::install_github("kassambara/ggpubr"))。

          假设您有 4 个地块 p1、p2、p3 和 p4。

          library(ggpubr)
          multi.page <- ggarrange(p1,p2,p3,p4, nrow=1, ncol=1) # for one plot per page
          multi.page[[1]] # for seeing the first plot
          ggexport(multi.page, filename="my-plots.pdf")
          

          更多ggpubr使用示例:http://www.sthda.com/english/articles/24-ggpubr-publication-ready-plots/81-ggplot2-easy-way-to-mix-multiple-graphs-on-the-same-page/

          【讨论】:

            【解决方案8】:

            没有gridExtra 包的好解决方案:

            library(plyr)
            library(ggplot2)
            
            li = structure(p, class = c("gglist", "ggplot"))
            print.gglist = function(x, ...) l_ply(x, print, ...)
            ggsave(li, file = "test.pdf")
            

            【讨论】:

              猜你喜欢
              • 2021-12-19
              • 2010-11-26
              • 2017-12-26
              • 1970-01-01
              • 2016-02-06
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2022-10-04
              相关资源
              最近更新 更多