【问题标题】:Multiple graphs over multiple pages using ggplot使用 ggplot 在多个页面上绘制多个图表
【发布时间】:2013-09-27 20:48:28
【问题描述】:

我正在对我的数据进行探索性分析,需要使用 ggplot 绘制多个图形。图形的数量非常庞大(206 个站),我想将它们绘制成 1 列而不是每页 8 行,需要的页面如此之多。我知道 viewport 或 grid.arrange 之类的功能,但我无法让它们在这种情况下工作。我已经注意到 layout() 和 par(mfrow=c(8,1)) 不能与 ggplot 一起使用,但是我发送了我卡在下面的代码部分。任何帮助将非常感激!

pdf('test.pdf', width=21, height=27)
par(mfrow=c(8,1))
for(i in levels(tab$Station))
{

print(ggplot(tab[tab$Station==i], aes(x=Date)) +
  geom_line(aes(y=Tmin), col="blue", size=0.1) + 
  geom_line(aes(y=Tmax), col="red", size=0.1) + 
  geom_text(aes(x=as.Date('2010-01-01'), y=45), label=i) +
  ylim(0, 45) + 
  scale_x_date(labels = date_format("%Y")) +
  theme_bw() +
  theme(
    plot.background = element_blank()
    ,panel.grid.major = element_blank()
    ,panel.grid.minor = element_blank()
    ,panel.border = element_rect(color = 'black')
    ,panel.background = element_blank()

  )
)

}

dev.off()

【问题讨论】:

  • 嗨,何塞,您介意将此作为可重复的示例吗?这通常意味着提供玩具数据,以便我们可以抓取代码并运行它。大多数情况下,人们使用data() 函数来执行此操作。例如 data(mtcars)mtcars data.frame 加载到内存中。
  • @baptiste 的回答有用吗?
  • 我知道这是一个老问题 - 但请尝试使用 ggforce 包中的 facet_wrap_paginate 函数。在此处查看帮助cran.r-project.org/web/packages/ggforce/ggforce.pdf 这就是我解决类似问题的方法。

标签: r ggplot2


【解决方案1】:
library(plyr)
library(gridExtra)

p = ggplot(tab, aes(x=Date)) +
       geom_line(aes(y=Tmin), col="blue", size=0.1)

plots = dlply(tab , "Station", `%+%`, e1 = p)
ml = do.call(marrangeGrob, c(plots, list(nrow=8, ncol=1)))
ggsave("multipage.pdf", ml)

未经测试。

【讨论】:

  • 你能解释一下你做了什么来创建上面的plots 对象吗? %+% 是做什么的?
  • %+% 覆盖 ggplot 中的数据
  • 我仍然是绿带,所以需要像你这样的 4 段黑带的帮助。此外,我现在才刚刚熟悉使用plyrdplyr 而不是apply 系列。所以我在这里猜测,但这是否意味着您已将子集 tab 对象(由 Station 子集)传递到 ggplot p,使用 %+% 函数覆盖 tab 参数所在的位置原本的?如果是这样,那就太棒了。
  • 比你@baptiste。请原谅后续,但e1 =dlply 函数中做了什么?当我删除它并将p 放在它的位置时,plots 函数仍然有效,但突然调用plots 对象导致没有图表出现。
  • %+% 是一个中缀运算符,有两个参数名为 e1e2。它的定义相当笨拙,这里感兴趣的案例考虑e1 一个ggplot 和e2 一个data.frame(实际上是其他东西)。默认情况下,dlply 循环(相当于 lapply)将向函数提供 data.frames 作为第一个参数,除非明确传递一个名为第一个参数的绘图(dlply 然后跳转到下一个参数)。
【解决方案2】:

你应该简化你的情节,因为一旦你用一个简单的情节得到了正确的顺序,你只需用复杂的情节代替它。 ggplot2 基于 grid 包,所以你需要使用 gridExtra 来安排你的情节。然后循环遍历,对于每 8 个图,将它们存储在一个列表中,然后在其上调用 grid.arrange,然后重复此操作直到图结束...

library(gridExtra)
library(ggplot2)
pdf('test.pdf', width=21, height=27)
i = 1
plot = list() 
for (n in unique(tab$Station)){
  ### process data for plotting here ####
  plot[[i]] = ggplot(tab[tab$Station==n], aes(x=Date)) +...
  if (i %% 8 == 0) { ## print 8 plots on a page
    print (do.call(grid.arrange,  plot))
    plot = list() # reset plot 
    i = 0 # reset index
  }
  i = i + 1
}
if (length(plot) != 0) { 
  print (do.call(grid.arrange,  plot))
}
dev.off()

【讨论】:

    【解决方案3】:

    刻面可能是要走的路。确定每页需要多少个小平面图,然后循环所需的次数,随时生成 png 或 pdf。因此,如果您有 200 个数据项并且您希望每页 50 个,在 5 个横向和 10 个向下的方面,只需循环 200/50 = 4 次迭代。粗鲁,但应该可以。

    library(ggplot2)
    
    ii <- 7
    nn <- 49
    
    mydf <- data.frame(date = rep(seq(as.Date('2013-03-01'),
                           by = 'day', length.out = ii), nn),
                       value = rep(runif(nn, 100, 200)))
    
    mydf$facet.variable <- rep(1:nn, each = ii)
    
    p <- ggplot(mydf, aes(x = date, y = value)) +
        geom_line() +
        facet_wrap(~ facet.variable, ncol = ii)
    
    print(p)
    

    【讨论】:

      【解决方案4】:

      很遗憾,mfrow 不适用于 ggplot2。您必须使用其他方法,例如 this onethis one 或使用本机 plot 函数。

      也许您可以使用 faceting 将 8 个图放在一个页面上,然后使用第二个链接将其放入多个文档中...

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-01-27
        • 2016-08-30
        相关资源
        最近更新 更多