use*_*544 0 pdf r heatmap ggplot2
我正在尝试在 R 中绘制由 ggplot 生成的大型热图。最终,我想使用 Illustrator 来“润色”此热图。
示例代码:
# Load packages (tidyverse)
library(tidyverse)
# Create dataframe
df <- expand.grid(x = seq(1,100000), y = seq(1,100000))
# add variable: performance
set.seed(123)
df$z <- rnorm(nrow(df))
ggplot(data = df, aes(x = x, y = y)) +
geom_raster(aes(fill = z))
Run Code Online (Sandbox Code Playgroud)
虽然我将绘图保存为矢量化图像(.pdf;那不是那么大),但打开时 pdf 的加载速度非常慢。我希望在打开文件时呈现数据框中的每个单独点。
我已经阅读了其他用于可视化矩阵的帖子(例如R 中的数据探索:显示大矩阵的热图,很快?)image(),但是我想使用 ggplot 来修改图像。
问题:如何加快此图的渲染速度?有没有办法(除了降低绘图的分辨率),同时保持图像矢量化,以加快这个过程?是否可以对矢量化 ggplot 进行下采样?
我尝试的第一件事是stat_summary_2d获得平均分档,但它看起来很慢,并且还在右边缘和上边缘产生了一些伪影:
library(tidyverse)
df <- expand.grid(x = seq(1,1000), y = seq(1,1000))
set.seed(123)
df$z <- rnorm(nrow(df))
print(object.size(df), units = "Mb")
#15.4 Mb
ggplot(data = df, aes(x = x, y = y, z = z)) +
stat_summary_2d(bins = c(100,100)) + #10x downsample, in this case
scale_x_continuous(breaks = 100*0:10) +
labs(title = "stat_summary_2d, 1000x1000 downsampled to 100x100")
Run Code Online (Sandbox Code Playgroud)
即使这比您建议的数据小得多,这仍然需要大约 3 秒才能在我的机器上绘制,并且在顶部和右侧边缘有伪影,我推测是因为这些 bin 从边缘开始较小,留下了更多的变化。
当我尝试像您要求的那样使用更大的网格时,它从那里变慢了。
(顺便说一句,可能值得澄清的是,像 PDF 这样的矢量图形文件与光栅图形不同,可以在不损失分辨率的情况下调整大小。但是,在这个用例中,输出是 10,000 兆像素的光栅文件,远远超出人类感知的极限,即被导出为矢量格式,其中每个“像素”成为 PDF 中的一个非常小的矩形。使用矢量格式在某些不寻常的情况下可能很有用,比如如果你需要炸毁你的热图在一个巨大的表面上没有分辨率损失,比如足球场。但听起来在这种情况下它可能是错误的工具,因为你将大量数据放入矢量文件中,这些数据不会可察觉。)
更有效的是对dplyrbefore进行平均ggplot。有了这个,我可以在发送到 ggplot 之前使用 10k x 10k 阵列并将其下采样 100 倍。这必然会降低分辨率,但我不明白在这个用例中保留超出人类感知能力的分辨率的价值。
这里有一些代码可以自己进行分桶,然后绘制下采样版本:
# Using 10k x 10k array, 1527.1 Mb when initialized
downsample <- 100
df2 <- df %>%
group_by(x = downsample * round(x / downsample),
y = downsample * round(y / downsample)) %>%
summarise(z = mean(z))
ggplot(df2, aes(x = x, y = y)) +
geom_raster(aes(fill = z)) +
scale_x_continuous(breaks = 1000*0:10) +
labs(title = "10,000x10,000 downsampled to 100x100")
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1961 次 |
| 最近记录: |