【问题标题】:Hundreds of plots with R ggplot用 R ggplot 绘制数百个图
【发布时间】:2019-08-29 15:12:40
【问题描述】:

我有 141 个数值变量的季度预测值和实际值,这些变量是针对 3 个不同国家/地区测量的。我想找出我的预测对于哪些变量“足够好”。当我进行一些早期探索时,我试图为 3 * 141 = 423 对(国家,变量)中的每一对绘制实际值和预测。我不知道如何用 ggplot2 制作那么多图。

我已经用所有变量融化了数据框,所以它现在有列:

 $ Date    : 'yearqtr' num  2017 Q1 2017 Q2 2017 Q3 2017 Q4 ...
 $ Country : Factor w/ 3 levels "CN","DE","US": 1 1 1 1 1 1 1 1 1 1 ...
 $ variable: Factor w/ 141 levels "BCU_D","BUSCONFM",..: 1 1 1 1 1 1 1 1 1 1 
 $ value   : num  21382 56639 45900 71196 -34100 ...
 $ isActual: logi  TRUE TRUE TRUE TRUE TRUE TRUE ...

然后,我尝试了一个简单的 ggplot 调用:

ggplot(meltedData, aes(x = Date, y = value, color = isActual)) + geom_line() + facet_wrap(Country ~ variable, ncol = 3) + scale_x_yearqtr(format = "%YQ%q", n = 5)

我得到的是一些无用的灰色框。

我想得到如上所述的 141 * 3 图表。

我想制作一个 141 页的 pdf 文档,为每个变量逐页绘制一组图,如果这样更容易的话。

谢谢!

============

@Gregor 建议的解决方案(循环变量)很令人满意:

for (this_variable in unique(meltedData$variable)) {
  g = ggplot(meltedData[meltedData$variable == this_variable, ],
             aes(x = Date, y = value, color = isActual)) +
               geom_line() +
               facet_wrap(. ~ Country, nrow = 3) + 
               scale_x_yearqtr(format = "%YQ%q", n = 5) + 
               labs(title = this_variable)
  ggsave(filename = paste0(this_variable, ".png"), plot = g, path = "output_graphs")
}

【问题讨论】:

  • 对两个变量使用 facet_grid 而不是 facet_wrap。重新考虑您是否真的想要在单个 pdf 页面上显示 141 x 3 的图...
  • ggforce 包有 facet_wrap()facet_grid() 的分页版本,这在绘制大量变量时可能会很方便。
  • @teunbrand,它看起来像一个有趣的包。检查the documentation for the paginated version of facetgrid,在我看来我们仍然需要使用 for 循环,所以最终的解决方案类似于 Gregor 的:我们将循环通过页码而不是循环通过变量,但原理是相同的。我说的对吗?
  • 这听起来与我从文档中理解的相似。我想保持一致性会有一点好处(例如,相同的轴限制每个页面),但如果您的轴是免费的,那将不是问题。

标签: r ggplot2 plot


【解决方案1】:

facet_wrap(或facet_grid)将为您提供一个绘图网格 - 您将无法在行之间进行分页。对于 141 行,您的选择是创建一个 非常 高的图像文件,可能太笨重而无法使用。

更好的方法是将每一行(或一组行)保存到不同的文件中。由于我没有您的数据,我无法测试解决方案,但这里有一个使用内置数据的示例:

library(ggplot2)
for (i in unique(mtcars$cyl)) {
  g = ggplot(mtcars[mtcars$cyl == i, ], aes(x = wt, y = mpg)) + 
    geom_point() +
    facet_wrap(~ am) +
    labs(title = paste("Cylinder:", i))
  ggsave(filename = paste0("cylinder_", i, ".png"), plot = g)
}

根据您的数据,我认为它看起来像这样(未经测试):

for(this_var in unique(meltedData$variable)) {
  g = ggplot(meltedData[meltedData$variable == this_var, ],
             aes(x = Date, y = value, color = isActual)) + 
    geom_line() + 
    facet_wrap(~ Country, ncol = 3) +
    scale_x_yearqtr(format = "%YQ%q", n = 5) +
    labs(title = this_var)
  ggsave(filename = paste0(this_var, ".png"), plot = g)
}

【讨论】:

  • 这是个好主意,非常感谢。我在最初的帖子中包含了最终解决方案。我稍微修改了一下:例如,我循环遍历变量而不是国家,因为我只有 3 个国家,但变量太多,无法将它们全部放在一张图像中。
  • 哈!我在那里的疏忽。真高兴你做到了。 (我也编辑了答案)
猜你喜欢
  • 2017-01-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-11-19
  • 2015-12-26
  • 2012-12-11
  • 1970-01-01
相关资源
最近更新 更多