r - 为什么我的 ggplot 对象变得这么大?

标签 r ggplot2 plot data-structures tidyverse

我正在尝试绘制具有 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。 enter image description here

这是用于生成这些图的代码

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`)

直方图的外观如下: 情节1: enter image description here

情节2: enter image description here

有什么方法可以减小这个 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_histgg_point 的对象大小(仅用于证明这一点的示例)几乎相同,它们都在内部存储原始数据,因此只是比 pc
  • 的原始大小稍大一点
  • gg_grob_hist 的对象大小比 gg_hist 小得多(gg_grob_point 的大小巨大,这并不奇怪,因为我们正在绘制 1e6 个单独的点)

我认为如果您想减小渲染的 PDF 的大小,有一些想法:

关于r - 为什么我的 ggplot 对象变得这么大?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/75594274/

相关文章:

python - 多次调用 pd.DataFrame.plot() 后颜色一致

matlab - 以编程方式向图形添加文本注释

matlab - 在 Matlab 中对齐图例文本

R 编程 - 将数字转换为 MM :SS

r - ggplot2 添加指向特定数据点的动态箭头注释,这些数据点与整个图的比例保持比例

r - 是否可以根据彼此之间的距离重新排列 GPS 点

R:在 ggplot 中使用 rollmean 会在最后产生错误的下降

r - 如何使用 y 作为 ggplot2 中每个 bin 的 x 值的总和绘制直方图

r - 如何一步获得带有嵌套的分组 Sum

java - rJava、mac 10.12.6 和 Java v 9(R 版本 3.4.1)的问题