如何避免ggplot生成PDF文件时出现重复图形对象?
ggplot2生成PDF时重复绘制图形元素的问题
之前发现ggplot(及基础绘图系统)生成PDF文件时会包含“不可见”数据,近期又注意到ggplot生成PDF时会绘制不必要的图形元素副本,副本数量与绘图所用数据框的观测数一致。
以mpg数据集(共234条观测)为例:
library(ggplot2) nrow(mpg) > 234
p <- ggplot(mpg, aes(class, hwy)) p + geom_boxplot()+ geom_segment(aes(x = 5, y = 40, xend = 6, yend = 40))+ geom_text(label = "***", x = 5.5, y = 41, size = 6) ggsave("mtcars.pdf")
生成的PDF中,geom_text生成234个“***”副本,这符合其帮助文档说明(geom_text() and geom_label() add labels for each row in the data);但geom_segment也生成了234个副本,尽管文档未提及该行为。
这种情况视觉上几乎不可见(仅元素看起来略粗),但会无端增大PDF体积,数据量大时影响更明显。目前仅验证了geom_segment,其他元素可能存在同样问题。
解决方法
核心原因是:当在geom_*的aes()内设置静态参数(如固定的x、y值)且未指定独立数据集时,ggplot会默认使用顶层数据集,为每一行观测绘制一次该元素。以下是几种有效解决方式:
使用
annotate()添加静态注释(推荐)annotate()专为添加非数据关联的静态元素设计,默认仅绘制一次,无需依赖顶层数据集:p <- ggplot(mpg, aes(class, hwy)) p + geom_boxplot()+ annotate("segment", x = 5, y = 40, xend = 6, yend = 40)+ annotate("text", label = "***", x = 5.5, y = 41, size = 6) ggsave("mtcars.pdf")将静态参数移出
aes()
对于无需映射数据的固定值,直接放在geom_*的参数中(而非aes()内),ggplot不会按数据集行数重复绘制:p <- ggplot(mpg, aes(class, hwy)) p + geom_boxplot()+ geom_segment(x = 5, y = 40, xend = 6, yend = 40)+ geom_text(label = "***", x = 5.5, y = 41, size = 6) ggsave("mtcars.pdf")为元素指定独立的单行数据集
给不需要重复绘制的geom指定仅含一行数据的数据集,限制其绘制次数:p <- ggplot(mpg, aes(class, hwy)) p + geom_boxplot()+ geom_segment(aes(x = 5, y = 40, xend = 6, yend = 40), data = data.frame())+ geom_text(label = "***", x = 5.5, y = 41, size = 6, data = data.frame()) ggsave("mtcars.pdf")
内容的提问来源于stack exchange,提问作者YGS
相关产品推荐
相关产品推荐

