【问题标题】:Efficiently plotting hundreds of millions of points in R在 R 中有效地绘制数亿个点
【发布时间】:2018-07-01 11:44:02
【问题描述】:

plot() 是在 R 中绘制大约 1 亿个数据点的最有效方法吗? 我想绘制一堆这些Clifford Attractors。这是我从一张非常大的图像中缩小的示例:

Here 是我用来绘制非常大的 8K (7680x4320) 图像的一些代码的链接。

生成 50 或 1 亿个点(使用 Rcpp)不需要很长时间,也没有得到颜色 + 透明度的 hex 值,但实际绘图和保存到磁盘是 非常慢的。

  • 是否有更快的方法来绘制(并保存)所有这些点?
  • 对于这项工作,R 只是一个糟糕的工具吗?
  • 您会使用哪些工具来绘制数十亿个点,即使您无法将它们全部放入内存中?
  • 如何使用 1990 年代的软件和硬件制作这种类型(颜色 + 透明度)的高分辨率绘图?

编辑:使用的代码

# Load packages
library(Rcpp)
library(viridis)

# output parameters
output_width = 1920 * 4
output_height = 1080 * 4
N_points = 50e6
point_alpha = 0.05 #point transperancy

# Attractor parameters
params <- c(1.886,-2.357,-0.328, 0.918)

# C++ function to rapidly generate points
cliff_rcpp <- cppFunction(
    "
    NumericMatrix cliff(int nIter, double A, double B, double C, double D) {
    NumericMatrix x(nIter, 2);
    for (int i=1; i < nIter; ++i) {
    x(i,0) = sin(A*x(i-1,1)) + C*cos(A*x(i-1,0));
    x(i,1) = sin(B*x(i-1,0)) + D*cos(B*x(i-1,1));
    }
    return x;
    }"
)

# Function for mapping a point to a colour
map2color <- function(x, pal, limits = NULL) {
    if (is.null(limits))
        limits = range(x)
    pal[findInterval(x,
                     seq(limits[1], limits[2], length.out = length(pal) + 1),
                     all.inside = TRUE)]
}

# Obtain matrix of points
cliff_points <- cliff_rcpp(N_points, params[1], params[2], params[3], params[4])

# Calculate angle between successive points
cliff_angle <- atan2(
    (cliff_points[, 1] - c(cliff_points[-1, 1], 0)),
    (cliff_points[, 2] - c(cliff_points[-1, 2], 0))
)

# Obtain colours for points
available_cols <-
    viridis(
        1024,
        alpha = point_alpha,
        begin = 0,
        end = 1,
        direction = 1
    )

cliff_cols <- map2color(
    cliff_angle,
    c(available_cols, rev(available_cols))
)


# Output image directly to disk
jpeg(
    "clifford_attractor.jpg",
    width = output_width,
    height = output_height,
    pointsize = 1,
    bg = "black",
    quality = 100

)
    plot(
        cliff_points[-1, ],
        bg = "black",
        pch = ".",
        col = cliff_cols
    )

dev.off()

【问题讨论】:

  • 只是出于好奇,png() 的速度与jpeg() 的速度相比如何?
  • 虽然我是一个老 R 瘾君子,但我不认为这是要走的路……谷歌搜索带我到 Julia 的这篇文章:hackernoon.com/drawing-2-7-billion-points-in-10s-ecc8c85ca8fa
  • 理想情况下,您需要一个可以处理此问题的 opengl 解决方案。我使用 scattergl 专门为此目的使用 plotly
  • 这篇文章是相关的:gis.stackexchange.com/questions/213225/…。虽然,我认为raster::rasterize() 更慢。
  • 这个问题可以在不同层次上并行化。一种方法是创建子区域的图像并在之后加入它们。

标签: r plot graphics strange-attractor


【解决方案1】:

我最近发现了 R 的 Scattermore 包,它比 R 的标准绘图函数快一个数量级。 scattermoreplot() 需要大约 2 分钟来绘制具有颜色和透明度的 100m 点,而 plot() 需要大约半小时。

【讨论】:

    【解决方案2】:

    我目前正在探索 datashader (http://www.datashader.org)。如果你愿意使用 python,这可能是一个优雅的解决方案。

    【讨论】:

    • 这是一个使用数据着色器的综合吸引子探索器:anaconda.org/jbednar/datashaderattractors/notebook;您可以将分辨率设置为您喜欢的任何内容。通过批量绘制(生成批次、绘制批次、重复)可以提高效率,但现在它更倾向于简单。
    【解决方案3】:

    也许 ggplo2 包中的 geom_hex() 可以作为解决方案? https://ggplot2.tidyverse.org/reference/geom_hex.html

    【讨论】:

    • 嗨@Sara,这不会达到预期的效果。我想保留尽可能多的细节,而不是对像素进行分类。
    猜你喜欢
    • 2016-04-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-10-24
    • 1970-01-01
    • 1970-01-01
    • 2020-07-24
    • 1970-01-01
    相关资源
    最近更新 更多