Эффективное построение сотен миллионов точек в R

Является plot() самый эффективный способ построить около 100 миллионов точек данных в R? Я хотел бы построить кучу этих Клиффордских Аттракторов. Вот пример, который я уменьшил с очень большого изображения:

Аттрактор Клиффорда

Вот ссылка на некоторый код, который я использовал для построения очень больших 8K (7680x4320) изображений.

Это не займет много времени, чтобы сгенерировать 50 или 100 миллионов точек (используя Rcpp) или получить шестнадцатеричное значение для цвета + прозрачность, но фактическое построение графика и сохранение на диск очень медленное.

  • Есть ли более быстрый способ построить (и сохранить) все эти точки?
  • 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()

3 ответа

Недавно я обнаружил пакет Scattermore для R, который примерно на порядок быстрее, чем стандартная функция графика R. scattermoreplot()занимает ~2 минуты, чтобы нарисовать 100 м точек с цветом и прозрачностью, в то время как plot()занимает около получаса.

В настоящее время я изучаю datashader ( http://www.datashader.org/). Если вы готовы работать с Python, это может быть элегантным решением проблемы.

Может быть, geom_hex() из пакета ggplo2 может быть решением? https://ggplot2.tidyverse.org/reference/geom_hex.html

Другие вопросы по тегам