我正在尝试绘制具有 17,953,026 个观测值的变量的直方图。该数据表的大小(以兆字节为单位)约为 144 MB。
当我使用 R 中最基本的 hist()
函数绘制这些数据时,生成的绘图对象非常小。但是当我使用 ggplot2 时,创建的“gg”对象非常大 - 144 MB 大小(与数据大小相同)。这会导致渲染此图需要很长时间。
“pc”是数据。它有一个变量“匹配长度”,其值介于 8 和 47 之间。“plot1”是 ggplot2 对象,“plot2”是 hist 对象。
以下是 R 中 object.size()
函数返回的大小。
pc = ~144 MB,plot1 = ~144 MB,plot2 = 2016 B。
这是用于生成这些图的代码
plot1 <- ggplot(data = pc, aes(x = `match length`)) +
geom_histogram(bins = 26, 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))
plot2 <- hist(pc$`match length`)
情节2:
有什么方法可以减小这个 ggplot2 对象的大小,这样当我渲染 RMarkdown 或 Quarto 报告时,就不会永远花费时间?
最佳答案
hist
(基本 R)返回具有基本直方图属性的list
,它不存储原始数据或有关图形对象本身的任何内容。一旦可以使用返回对象来重新创建绘图,但这与存储图形对象本身不同。在这种情况下,基本统计信息列表
的大小始终很小。为了更好地了解
hist
创建的对象的大小,我们可以记录它。见下文。ggplot2
返回包含原始数据的list
结构。这是必要的,因为图形对象是在上下文中专门渲染的。一旦渲染,图形对象不一定包含原始数据(当然取决于它的绘制方式......)。通常,基于 ggplot2 的图形涉及更多“事物”(主题派生),因此我预计绘图会稍大一些。这可以通过使用
主题
和其他方式来控制。
可重复的比较示例:
set.seed(42)
pc <- data.frame("match length" = sample(8:47, 1e6, replace = TRUE), check.names = FALSE)
head(pc)
# match length
# 1 44
# 2 8
# 3 32
# 4 17
# 5 43
# 6 25
生成图:
gg_hist <- ggplot(pc, aes(`match length`)) + geom_histogram()
gg_hist
gg_grob_hist <- recordPlot()
gg_point <- ggplot(pc, aes(`match length`)) + geom_point(y = 1)
gg_point
gg_grob_point <- recordPlot()
h <- hist(pc$`match length`)
base_grob_hist <- recordPlot()
对象比较:
object.size(pc)
# 4000736 bytes
object.size(h)
# 1840 bytes
object.size(base_grob_hist)
# 69256 bytes
object.size(gg_hist)
# 4006336 bytes
object.size(gg_grob_hist)
# 1346728 bytes
object.size(gg_point)
# 4005616 bytes
object.size(gg_grob_point)
# 104746152 bytes
注释:
- 虽然
h
非常小,但它的grob大小巨大非常小,可能是因为它实际上只是一些图形元素。 (已编辑,我认为它最初很大,因为在同一开发中的此图和其他图之间来回移动......奇怪,仍在研究这个。) gg_hist
和gg_point
的对象大小(仅用于证明这一点的示例)几乎相同,它们都在内部存储原始数据,因此只是比pc
的原始大小稍大一点
gg_grob_hist
的对象大小比gg_hist
小得多(gg_grob_point
的大小巨大,这并不奇怪,因为我们正在绘制 1e6 个单独的点)
我认为如果您想减小渲染的 PDF 的大小,有一些想法:
- 您是否正在插入其他包含点和/或更多元素的图形对象?
- rmarkdown 渲染的默认设置是包含基于矢量的图形,这在 PDF 中看起来要好得多,但会增加其大小;您可以尝试渲染为 PNG(也许参见 https://community.rstudio.com/t/how-can-i-render-ggplot-images-in-png-rather-than-pdf-in-order-to-speed-up-my-compiled-pdf-document/12133 )
关于r - 为什么我的 ggplot 对象变得这么大?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/75594274/