我正在使用plot()
超过 100 万个数据点,结果非常慢。
有什么方法可以提高速度,包括编程和硬件解决方案(更多的内存、显卡......)?
绘图数据存储在哪里?
(这个问题与Scatterplot with too many points密切相关,尽管这个问题关注的是在大散点图中看到任何东西的难度而不是性能问题......)
hexbin 图实际上向您展示了一些东西(不像@Roland 在评论中提出的散点图,它可能只是一个巨大的、缓慢的、blob),并且在我的机器上大约需要 3.5 秒,例如:
set.seed(101)
a<-rnorm(1E7,1,1)
b<-rnorm(1E7,1,1)
library(hexbin)
system.time(plot(hexbin(a,b))) ## 0.5 seconds, modern laptop
另一个稍慢的替代方案是 base-RsmoothScatter
函数:它绘制平滑密度加上所要求的尽可能多的极值点(在本例中为 1000)。
system.time(smoothScatter(a,b,cex=4,nr=1000)) ## 3.3 seconds
一个简单快捷的方法是设置pch='.'
. 性能如下图
x=rnorm(10^6)
> system.time(plot(x))
user system elapsed
2.87 15.32 18.74
> system.time(plot(x,pch=20))
user system elapsed
3.59 22.20 26.16
> system.time(plot(x,pch='.'))
user system elapsed
1.78 2.26 4.06
你看过 tabplot 包了吗?它专为大数据而设计 http://cran.r-project.org/web/packages/tabplot/我使用它比使用 hexbin 更快(甚至使用默认的向日葵图进行过度绘图)
我还认为 Hadley 在 DS 的博客上写了一些东西,修改 ggplot for big data 在http://blog.revolutionanalytics.com/2011/10/ggplot2-for-big-data.html
"""我目前正在与另一名学生 Yue Hu 合作,将我们的研究转化为强大的 R 包。""" 2011 年 10 月 21 日
也许我们可以问 Hadley 更新的 ggplot3 是否准备好
这个问题是在reticulate
R 中运行 Python 命令的包还不存在时提出的。
现在可以调用高效的matplotlib
Python 库来绘制大型数据集。
matplotlib
此处描述了 R 中的设置。
绘制 100 万个点matplotlib
大约需要 1.5 秒:
library(reticulate)
library(png)
mpl <- import("matplotlib")
mpl$use("Agg") # Stable non interactive back-end
plt <- import("matplotlib.pyplot")
mpl$rcParams['agg.path.chunksize'] = 0 # Disable error check on too many points
# generate points cloud
a <-rnorm(1E6,1,1)
b <-rnorm(1E6,1,1)
system.time({
plt$figure()
plt$plot(a,b,'.',markersize=1)
# Save figure
f <- tempfile(fileext='.png')
plt$savefig(f)
# Close figure
plt$close(plt$gcf())
# Show image
img <- readPNG(f)
grid::grid.raster(img)
# Close temporary file
unlink(f)
})
#> User System Total
#> 1.29 0.15 1.49
由reprex 包(v0.3.0)于 2020-07-26 创建
这里没有提到,但是绘制到高分辨率光栅图像是另一个合理的选择(如果你真的想绘制一个巨大的 blob :-))。创建速度会很慢,但生成的图像会是合理的大小,并且会很快打开。因为 PNG会根据相邻像素的相似性来压缩文件,所以随着分辨率的增大,blob 的外部(全白)和内部(全黑)不会占用更多存储空间 - 您所做的只是渲染更详细的斑点边缘。
set.seed(101)
a<-rnorm(1E7,1,1)
b<-rnorm(1E7,1,1)
png("blob.png",width=1000,height=1000)
system.time(plot(a,b)) ## 170 seconds on an old Macbook Pro
dev.off()
生成的图像文件为 123K,并且可以通过稍微增加渲染大小(创建和打开文件)和文件大小来获得更高的分辨率。