12

我正在通过更改 ggplot_build 生成的数据来修改使用 ggplot 构建的图形(原因类似于在 geom_boxplot 中填充美学中使用的包含缺失因子级别的空间)。据我了解我在这个主题上找到的帮助,我应该能够在调用 ggsave 之前应用 ggplot_gtable 和arrangeGrob 来保存结果(将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)

4

2 回答 2

23

它不起作用,因为ggsave需要一个 class 对象ggplot,而您正在传递一个 grob。arrangeGrob有时会ggsave假装继承自ggplot,但仅当至少有一个 grobs 属于此类时;但是,在这里,您只传递了一个gtable.

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

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

编辑: ggplot2 的开发版本不再需要这个 hack*,因为ggsave 现在可以与任何 grob 一起使用

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

于 2013-08-23T16:16:54.973 回答
1

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

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

于 2015-12-07T19:45:31.767 回答