web-dev-qa-db-fra.com

contrôler l'ordre des points dans ggplot2 dans R?

Supposons que je trace un diagramme de dispersion dense dans ggplot2 dans R où chaque point pourrait être étiqueté par une couleur différente:

df <- data.frame(x=rnorm(500))
df$y = rnorm(500)*0.1 + df$x
df$label <- c("a")
df$label[50] <- "point"
df$size <- 2
ggplot(df) + geom_point(aes(x=x, y=y, color=label, size=size))

Lorsque je fais cela, le point de dispersion étiqueté "point" (vert) est tracé au-dessus des points rouges qui ont l'étiquette "a". Qu'est-ce qui contrôle cet ordre z dans ggplot, c'est-à-dire ce qui contrôle quel point est au-dessus de qui? Par exemple, que se passe-t-il si je veux que tous les points "a" soient au-dessus de tous les points étiquetés "point" (ce qui signifie qu'ils masquent parfois partiellement ou complètement ce point)? Cela dépend-il de l'ordre alphanumérique des étiquettes? Je voudrais trouver une solution qui peut être facilement traduite en rpy2. Merci

46
user248237

ggplot2 Crée des tracés couche par couche et à l'intérieur de chaque couche, l'ordre de traçage est défini par le type geom. La valeur par défaut est de tracer dans l'ordre dans lequel ils apparaissent dans le data.

Lorsque cela est différent, c'est noté. Par exemple

geom_line

Connectez les observations, classées par valeur x.

et

geom_path

Connecter les observations dans l'ordre des données


Il y a aussi problèmes connus concernant la commande de factors , et il est intéressant de noter la réponse de l'auteur du paquet Hadley

L'affichage d'un tracé doit être invariant à l'ordre de la trame de données - tout le reste est un bug.


Cette citation à l'esprit, un calque est dessiné dans l'ordre spécifié, donc le surplacement peut peut être un problème, en particulier lors de la création de nuages ​​de points denses. Donc, si vous voulez un tracé cohérent (et pas un qui repose sur l'ordre dans la trame de données), vous devez réfléchir un peu plus.


Créer un deuxième calque

Si vous souhaitez que certaines valeurs apparaissent au-dessus d'autres valeurs, vous pouvez utiliser l'argument subset pour créer un deuxième calque à dessiner définitivement par la suite. Vous devrez charger explicitement le package plyr pour que .() fonctionne.

set.seed(1234)
df <- data.frame(x=rnorm(500))
df$y = rnorm(500)*0.1 + df$x
df$label <- c("a")
df$label[50] <- "point"
df$size <- 2
library(plyr)
ggplot(df) + geom_point(aes(x = x, y = y, color = label, size = size)) +
  geom_point(aes(x = x, y = y, color = label, size = size), 
             subset = .(label == 'point'))

enter image description here

Mise à jour

Dans ggplot2_2.0.0, L'argument subset est obsolète. Utilisez par exemple base::subset Pour sélectionner les données pertinentes spécifiées dans l'argument data. Et pas besoin de charger plyr:

ggplot(df) +
  geom_point(aes(x = x, y = y, color = label,  size = size)) +
  geom_point(data = subset(df, label == 'point'),
             aes(x = x, y = y, color = label, size = size))

Ou utilisez alpha

Une autre approche pour éviter le problème de surplotage serait de définir le alpha (transparence) des points. Cela ne sera pas aussi efficace que l'approche explicite de la deuxième couche ci-dessus, cependant, avec une utilisation judicieuse de scale_alpha_manual, Vous devriez être en mesure de faire fonctionner quelque chose.

par exemple

# set alpha = 1 (no transparency) for your point(s) of interest
# and a low value otherwise
ggplot(df) + geom_point(aes(x=x, y=y, color=label, size=size,alpha = label)) + 
  scale_alpha_manual(guide='none', values = list(a = 0.2, point = 1))

enter image description here

47
mnel

Mise à jour 2016:

L'ordre esthétique a été déprécié , donc à ce stade, l'approche la plus simple consiste à trier le data.frame de sorte que le point vert se trouve en bas et soit tracé en dernier. Si vous ne souhaitez pas modifier le data.frame d'origine, vous pouvez le trier lors de l'appel à ggplot - voici un exemple qui utilise %>% et arrange du package dplyr pour effectuer le tri à la volée:

library(dplyr)
ggplot(df %>%
         arrange(label),
       aes(x = x, y = y, color = label, size = size)) +
  geom_point()

enter image description here

Réponse originale de 2015 pour les versions de ggplot2 <2.0.0

Dans ggplot2, vous pouvez utiliser ordre esthétique pour spécifier l'ordre dans lequel les points sont tracés. Les derniers tracés apparaîtront en haut. Pour l'appliquer, vous pouvez créer une variable contenant l'ordre dans lequel vous souhaitez dessiner les points.

Pour mettre le point vert sur le dessus en le traçant après les autres:

df$order <- ifelse(df$label=="a", 1, 2)
ggplot(df) + geom_point(aes(x=x, y=y, color=label, size=size, order=order))

Ou pour tracer le point vert en premier et l'enterrer, tracez les points dans l'ordre inverse:

ggplot(df) + geom_point(aes(x=x, y=y, color=label, size=size, order=-order))

Pour cet exemple simple, vous pouvez ignorer la création d'une nouvelle variable de tri et simplement contraindre la variable label à un facteur, puis à un numérique:

ggplot(df) +
  geom_point(aes(x=x, y=y, color=label, size=size, order=as.numeric(factor(df$label))))
33
Sam Firke

La question fondamentale ici peut être reformulée comme ceci:

Comment contrôler les couches de mon tracé?

Dans le package 'ggplot2', vous pouvez le faire rapidement en divisant chaque couche différente en une commande différente. Penser en termes de couches demande un peu de pratique, mais cela se résume essentiellement à ce que vous voulez tracer en plus d'autres choses. Vous construisez de l'arrière-plan vers le haut.

Prep: Préparez les données d'échantillon. Cette étape n'est nécessaire que pour cet exemple, car nous n'avons pas de données réelles avec lesquelles travailler.

# Establish random seed to make data reproducible.
set.seed(1)

# Generate sample data.
df <- data.frame(x=rnorm(500))
df$y = rnorm(500)*0.1 + df$x

# Initialize 'label' and 'size' default values.
df$label <- "a"
df$size <- 2

# Label and size our "special" point.
df$label[50] <- "point"
df$size[50] <- 4

Vous remarquerez peut-être que j'ai ajouté une taille différente à l'exemple juste pour rendre la différence de calque plus claire.

Étape 1: Séparez vos données en couches. Faites toujours ceci AVANT d'utiliser la fonction 'ggplot'. Trop de gens sont bloqués en essayant de manipuler des données avec les fonctions 'ggplot'. Ici, nous voulons créer deux couches: une avec les étiquettes "a" et une avec les étiquettes "point".

df_layer_1 <- df[df$label=="a",]
df_layer_2 <- df[df$label=="point",]

Vous pouvez le faire avec d'autres fonctions, mais j'utilise rapidement la logique de correspondance des trames de données pour extraire les données.

Étape 2: tracez les données sous forme de couches. Nous voulons d'abord tracer toutes les données "a", puis tracer toutes les données "ponctuelles".

ggplot() + 
    geom_point(
        data=df_layer_1,
        aes(x=x, y=y), 
        colour="orange", 
        size=df_layer_1$size) +
    geom_point(
        data=df_layer_2, 
        aes(x=x, y=y), 
        colour="blue", 
        size=df_layer_2$size)

demo chart

Notez que la couche de tracé de base ggplot() n'a pas de données affectées. Ceci est important, car nous allons remplacer les données de chaque couche. Ensuite, nous avons deux couches de géométrie ponctuelle distinctes geom_point(...) qui utilisent leurs propres spécifications. Les axes x et y seront partagés, mais nous utiliserons des données, des couleurs et des tailles différentes.

Il est important de déplacer les spécifications de couleur et de taille en dehors de la fonction aes(...), afin que nous puissions spécifier ces valeurs littéralement. Sinon, la fonction "ggplot" attribuera généralement des couleurs et des tailles en fonction des niveaux trouvés dans les données. Par exemple, si vous avez des valeurs de taille de 2 et 5 dans les données, il attribuera une taille par défaut à toutes les occurrences de la valeur 2 et affectera une taille plus grande à toutes les occurrences de la valeur 5. An 'aes La spécification de fonction n'utilisera pas les valeurs 2 et 5 pour les tailles. Il en va de même pour les couleurs. J'ai des tailles et des couleurs exactes que je veux utiliser, donc je déplace ces arguments dans la fonction 'geom_plot' elle-même. De plus, toutes les spécifications de la fonction 'aes' seront mises dans la légende, ce qui peut être vraiment inutile.

Note finale: Dans cet exemple, vous pouvez obtenir le résultat souhaité de plusieurs manières, mais il est important de comprendre comment fonctionnent les couches 'ggplot2' afin de tirer le meilleur parti de vos graphiques 'ggplot'. Tant que vous séparez vos données en différentes couches avant d'appeler les fonctions "ggplot", vous avez beaucoup de contrôle sur la façon dont les choses seront représentées à l'écran.

12
Dinre

Il est tracé dans l'ordre des lignes du data.frame. Essaye ça:

df2 <- rbind(df[-50,],df[50,])
ggplot(df2) + geom_point(aes(x=x, y=y, color=label, size=size))

Comme vous le voyez, le point vert est tracé en dernier, car il représente la dernière ligne du data.frame.

Voici un moyen de commander le data.frame pour que le point vert soit d'abord dessiné:

df2 <- df[order(-as.numeric(factor(df$label))),]
7
Roland