【问题标题】:Saving a graph with ggsave after using ggplot_build and ggplot_gtable使用 ggplot_build 和 ggplot_gtable 后使用 ggsave 保存图形
【发布时间】:2013-08-26 18:01:02
【问题描述】:

我正在通过更改 ggplot_build 生成的数据来修改使用 ggplot 构建的图形(原因类似于 Include space for missing factor level used in fill aesthetics in geom_boxplot)。据我了解我在这个主题上找到的帮助,我应该能够通过应用 ggplot_gtable 和arrangeGrob 来保存结果,然后再调用 ggsave 结果 (Saving grid.arrange() plot to file)。

但是我得到一个错误“情节应该是一个 ggplot2 情节”,也有这个简单的可复制的例子:

require('ggplot2')
require('gridExtra')
df <- data.frame(f1=factor(rbinom(100, 1, 0.45), label=c("m","w")), 
                  f2=factor(rbinom(100, 1, 0.45), label=c("young","old")),
                  boxthis=rnorm(100))
g <- ggplot(aes(y = boxthis, x = f2, fill = f1), data = df) + geom_boxplot()
dd <- ggplot_build(g)

# Printing the graph works:
print(arrangeGrob(ggplot_gtable(dd)))

# Saving the graph doesn't:
ggsave('test.png',arrangeGrob(ggplot_gtable(dd)))

谁能解释为什么这不起作用?使用 ggplot_build() 修改数据后有没有办法使用 ggsave ?

(我的包版本是gridExtra_0.9.1和ggplot2_0.9.3.1)

【问题讨论】:

    标签: r ggplot2 ggsave


    【解决方案1】:

    它不起作用,因为 ggsave 想要一个 ggplot 类的对象,而你正在传递一个 grob。 arrangeGrob 有时会欺骗 ggsave 假装继承自 ggplot,但前提是至少有一个 grobs 属于此类;然而,在这里,你只是传递了一个gtable

    也许最简单的解决方法是克隆 ggsave 并绕过类检查,

    ggsave <- ggplot2::ggsave; body(ggsave) <- body(ggplot2::ggsave)[-2]
    

    编辑: ggplot2 的开发版不再需要这种 hack*,如 ggsave now works with any grob

    *PS:这个 hack 不再起作用了,因为arrangeGrob 现在返回一个 gtable,并且它的 print 方法不在设备上绘制。

    【讨论】:

    • 谢谢。这与 [link] (stackoverflow.com/a/20433318/2173340) 结合使用,解决了我使用 'gtable' 和 'ggsave' 保存由 'ggplot2' 创建的图的问题。
    • @baptiste 我尝试了覆盖ggsave 函数的技巧,但在我的情况下它不起作用。同时ggplot仍然是1.0.1,问题还没有解决。如果我使用您的方法,我会使用 ggsave('test.pdf', arrangeGrob(p1, p2)) 创建一个 pdf 文件,但它在某种程度上已损坏。同时gtable 会打印在控制台中。所以有些东西不能正常工作。
    • 我刚刚更新到 gridExtra_2.0.0 并安装了 ggplot2_1.0.1(这两个似乎都是 CRAN 上的最新版本)。正如您在更新中所述,arrangeGrob 现在返回一个 gtable,而ggsave 仍在测试绘图对象的类。我是否必须安装 ggplot 的开发版本才能保存使用安排Grob 完成的绘图?
    • 是的,请注意,ggplot2 更新意味着很快就会发布,上次我上个月检查过
    【解决方案2】:

    解决方法是使用 grid.draw() 绘制 gtable 对象,然后使用 dev.copy() 将绘图传输到文件。

    记得之后还要使用 dev.off()。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-08-28
      • 2018-10-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-03-02
      • 2018-02-08
      相关资源
      最近更新 更多