controlando el orden de puntos en ggplot2 en R?

Supongamos que estoy trazando un diagtwig de dispersión densa en ggplot2 en R, donde cada punto puede etiquetarse con un color diferente:

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

Cuando hago esto, el punto de dispersión etiquetado como “punto” (verde) se traza en la parte superior de los puntos rojos que tienen la etiqueta “a”. ¿Qué controla este ordenamiento z en ggplot, es decir, qué controla qué punto está encima de qué? Por ejemplo, ¿qué pasaría si quisiera que todos los puntos “a” estuvieran en la parte superior de todos los puntos etiquetados como “punto” (lo que significa que a veces ocultaría parcial o totalmente ese punto)? ¿Esto depende del orden alfanumérico de las tags? Me gustaría encontrar una solución que se pueda traducir fácilmente a rpy2. Gracias

ggplot2 creará gráficos capa por capa y dentro de cada capa, el orden de trazado se define por el tipo de geom . El valor predeterminado es trazar en el orden en que aparecen en los data .

Donde esto es diferente, se nota. Por ejemplo

geom_line

Conecte las observaciones, ordenadas por valor de x.

y

geom_path

Conecte las observaciones en orden de datos


También se conocen problemas relacionados con el orden de los factors , y es interesante observar la respuesta del autor del paquete, Hadley.

La visualización de un gráfico debe ser invariante según el orden del dataframe; cualquier otra cosa es un error.


Con esta cita en mente, una capa se dibuja en el orden especificado, por lo que la sobreimpresión puede ser un problema, especialmente cuando se crean diagtwigs de dispersión densos. Entonces, si quieres un argumento coherente (y no uno que dependa del orden en el dataframe) necesitas pensar un poco más.


Crea una segunda capa

Si desea que ciertos valores aparezcan sobre otros valores, puede usar el argumento del subset para crear una segunda capa que definitivamente se dibujará después. Deberá cargar explícitamente el paquete plyr para que plyr .() .

 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

Actualizar

En ggplot2_2.0.0 , el argumento del subset está en desuso. Utilice, por ejemplo, base::subset para seleccionar datos relevantes especificados en el argumento de data . Y no es necesario cargar 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)) 

O usa alpha

Otro enfoque para evitar el problema de la sobreimpresión sería establecer el alpha (transparencia) de los puntos. Esto no será tan efectivo como el anterior acercamiento explícito de la segunda capa, sin embargo, con el uso juicioso de scale_alpha_manual usted debería ser capaz de hacer que algo funcione.

p.ej

 # 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

Actualización 2016:

La orden estética ha quedado obsoleta , por lo que en este punto, el enfoque más fácil es ordenar el data.frame de modo que el punto verde esté en la parte inferior y se dibuje al final. Si no quiere alterar el data.frame original, puede ordenarlo durante la llamada a ggplot; aquí hay un ejemplo que usa %>% y arrange desde el paquete dplyr para hacer la ordenación sobre la marcha:

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

enter image description here

Respuesta original 2015 para versiones de ggplot2 <2.0.0

En ggplot2, puede usar el orden estético para especificar el orden en que se trazan los puntos. Los últimos trazados aparecerán en la parte superior. Para aplicar esto, puede crear una variable que contenga el orden en el que desea que se dibujen los puntos.

Para poner el punto verde en la parte superior trazándolo después de los otros:

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

O para trazar primero el punto verde y enterrarlo, trazar los puntos en el orden opuesto:

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

Para este ejemplo simple, puede omitir la creación de una nueva variable de clasificación y simplemente forzar la variable de label a un factor y luego a un valor numérico:

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

La pregunta fundamental aquí se puede reformular de esta manera:

¿Cómo controlo las capas de mi ttwig?

En el paquete ‘ggplot2’, puedes hacer esto rápidamente dividiendo cada capa diferente en un comando diferente. Pensar en términos de capas requiere un poco de práctica, pero básicamente se reduce a lo que quieres trazar encima de otras cosas. Construyes desde el fondo hacia arriba.

Preparación : prepare los datos de muestra. Este paso solo es necesario para este ejemplo, porque no tenemos datos reales para trabajar.

 # 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 

Puede notar que agregué un tamaño diferente al ejemplo solo para aclarar la diferencia de capa.

Paso 1 : separa tus datos en capas. Siempre haz esto ANTES de usar la función 'ggplot'. Demasiadas personas se atascan tratando de manipular datos con las funciones 'ggplot'. Aquí, queremos crear dos capas: una con las tags "a" y otra con las tags "punto".

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

Podría hacer esto con otras funciones, pero estoy usando rápidamente la lógica de coincidencia de marcos de datos para extraer los datos.

Paso 2 : grafica los datos como capas. Queremos trazar todos los datos "a" primero y luego graficar todos los datos de "puntos".

 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) 

cuadro de demostración

Tenga en cuenta que la capa de trazado base ggplot() no tiene datos asignados. Esto es importante, porque vamos a sobrescribir los datos para cada capa. Entonces, tenemos dos capas de geometría de punto separadas geom_point(...) que usan sus propias especificaciones. Los ejes xey serán compartidos, pero usaremos diferentes datos, colores y tamaños.

Es importante mover las especificaciones de color y tamaño fuera de la función aes(...) , por lo que podemos especificar estos valores literalmente. De lo contrario, la función 'ggplot' generalmente asignará colores y tamaños de acuerdo con los niveles encontrados en los datos. Por ejemplo, si tiene valores de tamaño de 2 y 5 en los datos, asignará un tamaño predeterminado a cualquier ocurrencia del valor 2 y asignará un tamaño mayor a cualquier ocurrencia del valor 5. La especificación de la función 'aes' no use los valores 2 y 5 para los tamaños. Lo mismo ocurre con los colores. Tengo tamaños y colores exactos que quiero usar, así que muevo esos argumentos a la función 'geom_plot'. Además, cualquier especificación en la función 'aes' se incluirá en la leyenda, lo que puede ser realmente inútil.

Nota final : en este ejemplo, puede lograr el resultado deseado de muchas maneras, pero es importante entender cómo funcionan las capas 'ggplot2' para aprovechar al máximo sus gráficos 'ggplot'. Siempre que separes tus datos en diferentes capas antes de llamar a las funciones 'ggplot', tienes mucho control sobre cómo se graficarán las cosas en la pantalla.

Se traza en orden de las filas en data.frame. Prueba esto:

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

Como puede ver, el punto verde se dibuja al final, ya que representa la última fila del data.frame.

Aquí hay una manera de ordenar que data.frame tenga el punto verde dibujado primero:

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