2010-07-02 8 views
13

El uso de position_jitter crea una fluctuación de fase aleatoria para evitar la sobreimpresión de los puntos de datos.¿Es posible oscilar dos gemas ggplot de la misma manera?

A continuación he utilizado el ejemplo de las estadísticas de béisbol para ilustrar mi problema. Cuando trazado los mismos datos con dos capas, la misma llamada de jitter inquieta a los geoms de forma un poco diferente. Esto tiene sentido porque presumiblemente genera el jitter aleatorio de forma independiente en las dos llamadas, pero produce el problema que se puede ver en mi gráfico a continuación.

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)) 

Aunque los puntos de barras de error y la línea se refieren a los mismos datos, que son inconexos-las líneas y los puntos no se conectan.

¿Existe una solución alternativa para esto? Pensé que esquivar posiciones podría ser la respuesta, pero no parece funcionar con este tipo de tramas. Alternativamente, tal vez haya alguna forma de obtener la llamada mean_cl_normal para también agregar las líneas? alt text http://img339.imageshack.us/img339/1807/screenshot20100702at943.png

Respuesta

7

Esta es una debilidad en la sintaxis actual de ggplot2; no hay forma de evitarla, excepto para agregar el jitter usted mismo.

O usted podría hacer algo como esto:

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: ¿se han realizado actualizaciones en ggplot2 desde que respondió a esto? – gvrocha

8

Creo que sí, mediante el establecimiento de la semilla que ser el mismo en los dos casos:

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)) 

Esto asegura que el generador de números aleatorios se envía de nuevo a la misma posición de partida que se utilizó en el llamada inicial. Sin embargo, no sé cómo podría extraer los incrementos aleatorios añadidos a los valores.

+0

¡Buena idea, pero no funcionó! Pensé que funcionaría, porque parece que position_jitter utiliza la trepidación del paquete base, que esperaba que utilizara el mismo generador de números aleatorios sembrado por set.seed. Supongo que una solución general sería crear mi propia versión jittered de x, pero espero que haya una mejor manera. –

+1

Eso no funcionará porque el jittering se realiza en tiempo de trazado, no en tiempo de creación. – hadley

+0

esto funcionó perfectamente para mí. Tal vez algo sobre una nueva versión desde que Hadley comentó (hace 4 años). Esta debería ser la nueva respuesta en lo que a mí respecta. – rcorty

1

que terminó generando una distribución uniforme de resolver este problema.

Hoy tuve que resolver el mismo problema subyacente. Creo un gráfico, agitando los puntos, y luego creo un segundo gráfico que esencialmente hace un acercamiento a una subsección del primero. Es disonante y distrae si los puntos se mueven.

A continuación se muestra una demostración del problema y mi solución. No uso ggplot para este argumento, pero se aplica el mismo concepto. Hago una distribución uniforme, un valor para cada valor que necesito para fluctuar. Lo agrego al marco de datos de origen para que cada vez que tome un subconjunto, el valor de la fluctuación de fase corresponda al mismo valor de datos originales.

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) 
    } 
Cuestiones relacionadas