Est plot()
la manière la plus efficace de tracer 100 millions de points de données environ dans R ? J'aimerais en tracer quelques-uns. Attracteurs de Clifford . Voici un exemple d'une image que j'ai réduite à partir d'une très grande image :
Aquí Voici un lien vers un code que j'ai utilisé pour tracer une très grande image 8K (7680x4320).
Il ne faut pas longtemps pour générer 50 ou 100 millions de points (à l'aide de Rcpp), ni pour obtenir la valeur hexadécimale de la couleur + la transparence, mais le tracé proprement dit et la sauvegarde sur le disque sont extrêmement lent.
- Existe-t-il un moyen plus rapide de tracer (et de sauvegarder) tous ces points ?
- R est-il simplement un mauvais outil pour ce travail ?
- Quels outils utiliseriez-vous pour tracer les points des milliards, même si vous ne pouviez pas tous les faire rentrer dans le bélier ?
- Comment aurait-on fait un tracé de très haute résolution de ce type (couleur + transparence) avec les logiciels et le matériel des années 1990 ?
Edit : code utilisé
# 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()
0 votes
Peut-être utiliser
image
au lieu deplot
?0 votes
@KarstenW. J'y ai pensé, mais il faudrait que je fasse moi-même le mappage des millions de points sur un emplacement de pixel et que je détermine la couleur correcte lorsque 2 points ou plus se retrouvent sur le même pixel. C'est quelque chose que je ne sais pas faire efficacement, mais je pourrais probablement jouer avec.
1 votes
Juste par curiosité, comment la vitesse du
png()
comparer avec celle dejpeg()
?0 votes
Pour ce qui est du traitement de plusieurs points sur un même pixel, vous pouvez regrouper les points par pixel : stackoverflow.com/questions/38822718/creating-2d-bins-in-r
0 votes
@BenBolker, je n'ai pas comparé les timings, mais les deux sont très lents.
0 votes
@Pere, je vais essayer d'y jeter un œil, mais il pourrait être difficile d'obtenir la couleur correcte pour chaque case. La couleur des cases n'est pas seulement une fonction du nombre de points dans chaque case. Dans le graphique, la couleur du point est fonction de l'angle entre les deux derniers points.
2 votes
Bien que je sois une vieille accro de R, je ne pense pas que ce soit la voie à suivre... Une recherche sur Google m'a conduit à ce post avec Julia : hackernoon.com/drawing-2-7-billion-points-in-10s-ecc8c85ca8fa
0 votes
Merci @EricLecoutre, lien informatif. Les diapositives référencées, slideshare.net/continuumio/ qui a l'air fantastique mais malheureusement il n'y a pas d'interface pour R. Explication de la raison : github.com/bokeh/datashader/issues/304
3 votes
Idéalement, vous voulez une solution opengl, quelque chose qui peut gérer cela. J'utilise plotly spécifiquement dans ce but en utilisant scattergl.
1 votes
Ce billet est lié : gis.stackexchange.com/questions/213225/ . Bien que, je pense
raster::rasterize()
est plus lent.2 votes
Le problème peut être parallélisé à différents niveaux. Une approche consisterait à créer des images de sous-régions et à les joindre ensuite.
0 votes
@Florian c'est une excellente idée !