ggplot2绘图对象体积过大的优化方法咨询
ggplot2绘图对象体积过大的优化方法咨询
你遇到的这个问题其实很常见——ggplot2默认会把整个原始数据集存储在生成的绘图对象里,而基础的hist()函数只保留了统计后的频数、区间等汇总信息,这就是为什么两者体积差这么大的原因。要解决这个问题,核心思路就是先对数据做统计汇总,再用汇总后的小数据集来绘图,这样ggplot对象就不会再拖着144MB的原始数据了。
方法一:手动汇总数据后用geom_col绘制
既然你的match length取值范围是8到47,而且绘图时只用到8到32的数据,我们可以先统计每个长度对应的观测数量,再用柱状图来模拟直方图的效果(两者视觉上几乎一致):
library(dplyr) # 第一步:汇总每个match length的频数 pc_summary <- pc %>% count(`match length`, name = "count") %>% # 统计频数,结果列命名为count filter(`match length` >= 8, `match length` <= 32) # 过滤到需要的区间 # 第二步:用汇总后的数据绘图 plot1_optimized <- ggplot(data = pc_summary, aes(x = `match length`, y = count)) + geom_col(fill = '#d90050', color = 'white', alpha = 0.5, linewidth = 0.05) + scale_x_continuous(breaks = seq(8,32,2), limits = c(8,32)) + labs(title = 'k = 10', x = 'Match length', y = 'Count') + theme_gray(base_size = 10, base_family = "Helvetica") + theme(legend.position = "top", plot.title = element_text(size = 12), axis.text = element_text(size = 8), axis.title = element_text(size = 8))
汇总后的pc_summary只有25行左右的数据,生成的plot1_optimized体积会和plot2差不多,渲染起来速度会快很多。
方法二:利用基础hist()的统计结果
如果你习惯用hist()的区间划分逻辑,也可以先让hist()计算好统计结果,再把结果传给ggplot:
# 先让hist()计算统计信息,不绘图 hist_stats <- hist(pc$`match length`, breaks = seq(8, 33, 1), plot = FALSE) # 把统计结果转成数据框 pc_summary2 <- data.frame( match_length_mid = hist_stats$mids, # 区间中点 count = hist_stats$counts # 区间内的频数 ) # 用这个汇总数据绘图 plot1_optimized2 <- ggplot(pc_summary2, aes(x = match_length_mid, y = count)) + geom_col(fill = '#d90050', color = 'white', alpha = 0.5, linewidth = 0.05, width = 1) + scale_x_continuous(breaks = seq(8,32,2), limits = c(8,32)) + labs(title = 'k = 10', x = 'Match length', y = 'Count') + theme_gray(base_size = 10, base_family = "Helvetica") + theme(legend.position = "top", plot.title = element_text(size = 12), axis.text = element_text(size = 8), axis.title = element_text(size = 8))
额外小技巧
如果之后你还遇到类似的大样本ggplot对象体积问题,也可以在绘图后用ggplot_build()提取绘图所需的计算结果,或者直接用ggsave()直接输出图片而不保存大对象,不过最根本的还是避免让ggplot携带原始大数据集,用汇总后的统计数据绘图是最优解。
备注:内容来源于stack exchange,提问作者Hrishikesh Hardikar
相关产品推荐
相关产品推荐

