web-dev-qa-db-fra.com

Nuage de points avec trop de points

J'essaie de tracer deux variables où N = 700K. Le problème est qu'il y a trop de chevauchement, de sorte que l'intrigue devient principalement un bloc noir solide. Existe-t-il un moyen de créer un "nuage" en niveaux de gris dans lequel l'obscurité de l'intrigue est fonction du nombre de points dans une région? En d'autres termes, au lieu de montrer des points individuels, je veux que l'intrigue soit un "nuage", plus le nombre de points dans une région est important, plus cette région est sombre.

112
user702432

Une des solutions consiste à utiliser le fondu alpha, ce qui rend chaque point légèrement transparent. Ainsi, les régions apparaissent plus sombres et comportent plus de points.

C'est facile à faire dans ggplot2:

df <- data.frame(x = rnorm(5000),y=rnorm(5000))
ggplot(df,aes(x=x,y=y)) + geom_point(alpha = 0.3)

enter image description here

Un autre moyen pratique de gérer cela est (et probablement plus approprié pour le nombre de points que vous avez) est le binning hexagonal:

ggplot(df,aes(x=x,y=y)) + stat_binhex()

enter image description here

Et il y a aussi des vieux binning rectangulaires réguliers (image omise), qui ressemblent davantage à votre carte thermique traditionnelle:

ggplot(df,aes(x=x,y=y)) + geom_bin2d()
138
joran

Vous pouvez également consulter le package ggsubplot. Ce package implémente les fonctionnalités présentées par Hadley Wickham en 2011 ( http://blog.revolutionanalytics.com/2011/10/ggplot2-for-big-data.html ).

(Dans la suite, j'inclus la couche "points" à des fins d'illustration.)

library(ggplot2)
library(ggsubplot)

# Make up some data
set.seed(955)
dat <- data.frame(cond = rep(c("A", "B"), each=5000),
                  xvar = c(rep(1:20,250) + rnorm(5000,sd=5),rep(16:35,250) + rnorm(5000,sd=5)),
                  yvar = c(rep(1:20,250) + rnorm(5000,sd=5),rep(16:35,250) + rnorm(5000,sd=5)))


# Scatterplot with subplots (simple)
ggplot(dat, aes(x=xvar, y=yvar)) +
  geom_point(shape=1) +
  geom_subplot2d(aes(xvar, yvar,
                     subplot = geom_bar(aes(rep("dummy", length(xvar)), ..count..))), bins = c(15,15), ref = NULL, width = rel(0.8), ply.aes = FALSE)

enter image description here

Cependant, cette fonctionnalité comporte des roches si vous avez une troisième variable à contrôler.

# Scatterplot with subplots (including a third variable) 

ggplot(dat, aes(x=xvar, y=yvar)) +
  geom_point(shape=1, aes(color = factor(cond))) +
  geom_subplot2d(aes(xvar, yvar,
                     subplot = geom_bar(aes(cond, ..count.., fill = cond))),
                 bins = c(15,15), ref = NULL, width = rel(0.8), ply.aes = FALSE)  

enter image description here

Ou une autre approche consisterait à utiliser smoothScatter():

smoothScatter(dat[2:3])

enter image description here

56
majom

Le mélange alpha est également facile à réaliser avec les graphiques de base.

df <- data.frame(x = rnorm(5000),y=rnorm(5000))
with(df, plot(x, y, col="#00000033"))

Les six premiers chiffres après le # sont la couleur en hexadécimal RVB et les deux derniers sont l'opacité, à nouveau en hexadécimal, soit 33 ~ 3/16e opaque.

enter image description here

50
Aaron

Vous pouvez également utiliser des courbes de niveau de densité (ggplot2):

df <- data.frame(x = rnorm(15000),y=rnorm(15000))
ggplot(df,aes(x=x,y=y)) + geom_point() + geom_density2d()

enter image description here

Ou combinez des contours de densité avec un mélange alpha:

ggplot(df,aes(x=x,y=y)) + 
    geom_point(colour="blue", alpha=0.2) + 
    geom_density2d(colour="black")

enter image description here

44
ROLO

Un aperçu de plusieurs bonnes options dans ggplot2:

library(ggplot2)
x <- rnorm(n = 10000)
y <- rnorm(n = 10000, sd=2) + x
df <- data.frame(x, y)

Option A: points transparents

o1 <- ggplot(df, aes(x, y)) +
  geom_point(alpha = 0.05)

Option B: ajouter des contours de densité

o2 <- ggplot(df, aes(x, y)) +
  geom_point(alpha = 0.05) +
  geom_density_2d()

Option C: ajouter des contours de densité remplis

o3 <- ggplot(df, aes(x, y)) +
  stat_density_2d(aes(fill = ..level..), geom = 'polygon') +
  scale_fill_viridis_c(name = "density") +
  geom_point(shape = '.')

Option D: carte de densité

o4 <- ggplot(df, aes(x, y)) +
  stat_density_2d(aes(fill = ..density..), geom = 'raster', contour = FALSE) +       
  scale_fill_viridis_c() +
  coord_cartesian(expand = FALSE) +
  geom_point(shape = '.', col = 'white')

Option E: hexbins

o5 <- ggplot(df, aes(x, y)) +
  geom_hex() +
  scale_fill_viridis_c() +
  geom_point(shape = '.', col = 'white')

Option F: tapis

o6 <- ggplot(df, aes(x, y)) +
  geom_point(alpha = 0.1) +
  geom_rug(alpha = 0.01)

Combinez en une figure:

cowplot::plot_grid(o1, o2, o3, o4, o5, o6,
                   ncol = 2, labels = 'AUTO', align = 'v', axis = 'lr')

 enter image description here

35
Axeman

Vous pouvez trouver utile le paquetage hexbin. Depuis la page d’aide de hexbinplot:

library(hexbin)
mixdata <- data.frame(x = c(rnorm(5000),rnorm(5000,4,1.5)),
                      y = c(rnorm(5000),rnorm(5000,2,3)),
                      a = gl(2, 5000))
hexbinplot(y ~ x | a, mixdata)

hexbinplot

28
Oscar Perpiñán

Ma méthode préférée pour tracer ce type de données est celle décrite dans cette question - un diagramme de densité de dispersion. L'idée est de faire un nuage de points mais de colorer les points en fonction de leur densité (grosso modo, la quantité de chevauchement dans cette zone).

Il simultanément:

  • indique clairement l'emplacement des valeurs aberrantes, et
  • révèle toute structure dans la zone dense de la parcelle.

Voici le résultat de la réponse du haut à la question liée:

 scatter-density plot

0
Stephen McAteer