【问题标题】:Speed up plot() function for large dataset加速大型数据集的 plot() 函数
【发布时间】:2012-06-08 08:49:45
【问题描述】:

我使用 plot() 处理超过 100 万个数据点,结果非常慢。

有没有什么方法可以提高速度,包括编程和硬件解决方案(更多内存、显卡...)?

绘图数据存储在哪里?

【问题讨论】:

  • 汇总数据并绘制摘要。
  • 我需要直观地绘制和观察数据
  • 你能提供更多关于你正在使用哪些绘图功能的信息吗?无论您使用的是基本图形、格子还是 ggplot,都会有很大的不同。
  • 这个问题需要更多的上下文才能得到有用的回答;当您绘制超过 100 万个数据点时,您希望看到什么? stackoverflow.com/questions/10806404/… 是相关的。
  • 什么 abt chart_Series 并使用基本图形绘制?

标签: r plot


【解决方案1】:

(这个问题与Scatterplot with too many points 密切相关,尽管这个问题关注的是在大散点图中很难看到任何东西,而不是性能问题......)

十六进制图实际上向您展示了一些东西(与 @Roland 在 cmets 中提出的散点图不同,它可能只是一个巨大的、缓慢的、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-R smoothScatter 函数:它绘制平滑密度加上请求的极值点(在本例中为 1000)。

system.time(smoothScatter(a,b,cex=4,nr=1000))  ## 3.3 seconds

【讨论】:

  • 这是很重要的一点:没有人可以吸收数百万甚至数千点的含义(可能除了一些“艺术”分形图 :-)),所以找到一种方法来聚类或否则减少要绘制的项目的大小。
  • 我不知道这个包,您的回答有助于在我正在准备的论文中呈现结果的特定问题。为此+1。但是,问题仍然存在:绘图时有什么限制?只是 CPU 功率还是其他原因?
  • 设备驱动程序不能很好地处理如此大的绘图任务。绘制单个点有很多开销。这不仅仅是两个数字,还需要考虑着色和透明度功能。不仅仅是 R。当给定一张需要渲染数百万个点的图像时,PDF 查看器会陷入相当大的困境。
  • 使用pch="."实际上可以节省很多时间;您可以通过(例如)直接绘制到 PNG 而不是屏幕或 PDF 来加快速度(这也会使最终绘图的大小更小)
【解决方案2】:

一个简单快捷的方法是设置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 

【讨论】:

    【解决方案3】:

    你看过 tabplot 包了吗?它专为大数据而设计 http://cran.r-project.org/web/packages/tabplot/ 我使用它比使用 hexbin(甚至是默认的向日葵地块进行过度绘制)更快

    我还认为 Hadley 在 DS 的博客上写了一些东西,在 http://blog.revolutionanalytics.com/2011/10/ggplot2-for-big-data.html 为大数据修改 ggplot

    """我目前正在与另一名学生 Yue Hu 一起工作,以将我们的研究转化为强大的 R 包。""" 2011 年 10 月 21 日

    也许我们可以询问 Hadley 更新后的 ggplot3 是否准备好

    【讨论】:

      【解决方案4】:

      这个问题是在 reticulate 从 R 运行 Python 命令的包还不存在时提出的。

      现在可以调用高效的matplotlib Python library 来绘制大型数据集。

      R 中的matplotlib 设置描述为here

      使用matplotlib 绘制 100 万个点大约需要 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 package (v0.3.0) 于 2020 年 7 月 26 日创建

      【讨论】:

        【解决方案5】:

        这里没有提到,但是绘制到高分辨率光栅图像是另一个合理的选择(如果你真的想绘制一个巨大的 blob :-))。创建速度会很慢,但生成的图像会是合理的大小,并且会很快打开。因为 PNGcompress the file based on similarity of neighboring pixels,所以随着分辨率的增大,blob 的外部(全白)和内部(全黑)不会占用更多存储空间 - 您所做的只是渲染 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,并且可以通过稍微增加渲染大小(创建和打开文件)和文件大小来获得更高的分辨率。

        【讨论】:

          猜你喜欢
          • 2021-06-29
          • 2011-01-10
          • 1970-01-01
          • 1970-01-01
          • 2022-01-25
          • 2016-12-30
          • 2012-12-31
          • 1970-01-01
          • 2013-04-27
          相关资源
          最近更新 更多