2010-07-02 14 views
13

L'utilisation de position_jitter crée une gigue aléatoire pour éviter le sur-remplissage des points de données.Est-il possible de gicler deux geoms ggplot de la même manière?

Dans le tableau ci-dessous, j'ai utilisé l'exemple des statistiques de baseball pour illustrer mon problème. Lorsque je tracerai les mêmes données avec deux couches, le même appel de gigue perturbe un peu les geoms. Cela a du sens car il génère vraisemblablement la gigue aléatoire indépendamment dans les deux appels, mais donne le problème que vous pouvez voir dans mon graphique ci-dessous.

p=ggplot(baseball,aes(x=round(year,-1),y=sb,color=factor(lg))) 
p=p+stat_summary(fun.data="mean_cl_normal",position=position_jitter(width=3,height=0))+coord_cartesian(ylim=c(0,40)) 
p+stat_summary(fun.y=mean,geom="line",position=position_jitter(width=3,height=0)) 

Bien que les points de barre d'erreur et la ligne se réfèrent aux mêmes données, ils sont disjoints-les lignes et les points ne se connectent pas.

Y a-t-il une solution de rechange à ce problème? Je pensais que la position Dodge pourrait être la réponse, mais cela ne semble pas fonctionner avec ce genre de complots. Alternativement, peut-être y at-il un moyen d'obtenir l'appel mean_cl_normal pour ajouter également les lignes? alt text http://img339.imageshack.us/img339/1807/screenshot20100702at943.png

Répondre

7

Ceci est une faiblesse de la syntaxe ggplot2 actuelle - il n'y a aucun moyen de contourner le problème, sauf pour ajouter la gigue vous-même.

Ou vous pourriez faire quelque chose comme ceci:

ggplot(baseball, aes(round(year,-1) + as.numeric(factor(lg)), sb, color = factor(lg))) + 
    stat_summary(fun.data="mean_cl_normal") + 
    stat_summary(fun.y=mean,geom="line") + 
    coord_cartesian(ylim=c(0,40)) 
+2

hadley: des mises à jour ont-elles été apportées à ggplot2 depuis que vous y avez répondu? – gvrocha

8

Je pense, en mettant la semence d'être le même dans les deux cas:

p=ggplot(baseball,aes(x=round(year,-1),y=sb,color=factor(lg))) 
myseed = 2010 
set.seed(myseed) 
p=p+stat_summary(fun.data="mean_cl_normal", 
    position=position_jitter(width=3,height=0))+coord_cartesian(ylim=c(0,40)) 
set.seed(myseed) 
p+stat_summary(fun.y=mean,geom="line", 
      position=position_jitter(width=3,height=0)) 

Cela garantit que le générateur de nombres aléatoires est renvoyé à la même position de départ que celle utilisée dans le appel initial. Cependant, je ne sais pas comment vous pourriez extraire les incréments aléatoires ajoutés aux valeurs.

+0

Bonne idée, mais cela n'a pas fonctionné! Je pensais que ça marcherait, car on dirait que position_jitter utilise la gigue du paquet de base, ce que j'espérais utiliser avec le même générateur de nombres aléatoires que seed.seed. Je suppose qu'une solution de contournement générale serait de créer ma propre version jittered de x, mais j'espère qu'il y a un meilleur moyen. –

+1

Cela ne fonctionnera pas parce que l'instabilité est faite au moment de l'intrigue, pas au moment de la création. – hadley

+0

cela a fonctionné parfaitement pour moi. Peut-être quelque chose à propos d'une nouvelle version depuis hadley commenté (il y a 4 ans). Cela devrait être la nouvelle réponse en ce qui me concerne. – rcorty

1

j'ai fini par générer une distribution uniforme pour résoudre ce problème.

Je devais résoudre le même problème sous-jacent aujourd'hui. Je crée une intrigue, jittering les points, puis je crée un deuxième complot qui zoom essentiellement sur une sous-section de la première. C'est dissonant et distrayant si les points se déplacent.

Voici une démo du problème et de ma solution. Je n'utilise pas ggplot pour cette intrigue, mais le même concept s'applique. Je fais une distribution uniforme, une valeur pour chaque valeur que j'ai besoin de gigue. Je l'ajoute à la base de données source de sorte que chaque fois que je prends un sous-ensemble, la valeur de gigue correspond à la même valeur de données d'origine.

data(airquality) 
someDataset= airquality 
someDataset$color="black" 
someDataset$color[someDataset$Month==8 & someDataset$Wind==9.7]="red" 
## jitter gives different results each time it's run 
for (fZoom in c(TRUE, FALSE)){ 
    if (fZoom) myAirQuality = someDataset[someDataset $Wind >7.5 & someDataset $Wind < 11.5,] 
    else myAirQuality = someDataset[someDataset $Wind >8.5 & someDataset $Wind < 10.5,] 
    quartz("Using Jitter") 
    plot(myAirQuality $Wind ~ jitter(myAirQuality $Month), col= myAirQuality$color) 
    } 

someDataset$MonthJit=runif(nrow(someDataset), min=-0.2, max=0.2) 
for (fZoom in c(TRUE, FALSE)){ 
    if (fZoom) myAirQuality = someDataset[someDataset $Wind >7.5 & someDataset $Wind < 11.5,] 
    else myAirQuality = someDataset[someDataset $Wind >8.5 & someDataset $Wind < 10.5,] 
    quartz("Using runif") 
    plot(myAirQuality $Wind ~ c(myAirQuality $Month + myAirQuality $MonthJit), col= myAirQuality$color) 
    }