R语言 为什么我的ggplot对象变得这么大?

anauzrmj  于 2023-03-05  发布在  其他
关注(0)|答案(1)|浏览(162)

我试图绘制一个有17,953,026个观测值的变量的直方图。这个数据表的大小(以兆字节为单位)是~144 MB。当我在R中使用最基本的hist()函数绘制这个数据时,产生的绘图对象的大小非常小。但是当我使用ggplot 2时,创建的'gg'对象很大-- 144 MB(与数据大小相同)。2这导致绘制这个图要花很长时间。
“pc”是数据。它有一个变量“match length”,取值范围为8到47。“plot 1”是ggplot 2对象,“plot 2”是hist对象。
以下是object.size()函数在R中返回的大小。pc = ~144 MB,plot 1 = ~144 MB,plot 2 = 2016 B。x1c 0d1x
以下是用于生成这些图的代码

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:

绘图2:

有没有什么方法可以减小ggplot 2对象的大小,这样当我呈现RMarkdown或夸托报表时,就不会花很长时间?

bxpogfeg

bxpogfeg1#

  • hist(base R)返回一个带有基本直方图属性的list,它不存储原始数据或任何关于图形对象本身的内容。一旦可以使用返回对象来 * 重新创建 * 绘图,但这与存储图形对象本身不同。在这种情况下,基本统计数据的list的大小总是很小。

为了更好地了解hist创建的对象的大小,我们可以记录它。

  • ggplot2返回一个包含原始数据的list-结构。这是必要的,因为图形对象是在上下文中专门呈现的。一旦呈现,图形对象就不一定包含原始数据(当然,这取决于它是如何绘制的...)。

一般来说,基于ggplot2的图形涉及的"东西"(主题衍生)要多得多,所以我预计出图会稍微大一些,这可以通过使用theme等方式来控制。
用于比较的可重现示例:

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渲染的大小,一些想法:

相关问题