Cómo dibujar polígonos limpios alrededor de regiones de diagrama de dispersión en ggplot2 [cerrado]

32

¿Cómo agrego un polígono limpio alrededor de un grupo de puntos en un diagrama de dispersión? Estoy usando ggplot2 pero estoy decepcionado con los resultados de geom_polygon.

El conjunto de datos está allí , como un archivo de texto delimitado por tabulaciones. El siguiente gráfico muestra dos medidas de actitudes hacia la salud y el desempleo en muchos países:

scatterplot with density2d

Me gustaría cambiar de geom_density2dmenos sofisticado pero empíricamente más correcto geom_polygon. El resultado en datos no clasificados no es útil:

enter image description here

¿Cómo dibujo polígonos 'limpios' que se comporten como rutas de contorno alrededor de los valores min-max yx? Traté de ordenar los datos en vano.

Código:

print(fig2 <- ggplot(d, aes(man, eff, colour=issue, fill=issue)) + 
geom_point() + geom_density2d(alpha=.5) + labs(x = "Efficiency", y = "Mandate"))

El dobjeto se obtiene con este archivo CSV .

Solución:

Gracias a Wayne , Andy W y otros por sus consejos! Los datos, el código y los gráficos se han publicado en GitHub . El resultado se ve así:

result

El p.
fuente
66
El término que podría estar buscando es el casco convexo de los puntos (o potencialmente el casco alfa). Debería poder encontrar una función R para calcularlas y luego poder agregarlas como capas a la gráfica.
Andy W
¡Gracias por señalar la terminología correcta! No he podido usar ?chullcon ggplot2hasta ahora. No estoy seguro de que lo estoy codificando correctamente, y espero que alguien ya lo haya hecho.
p.
¿Podría agregar su código R a la pregunta?
Yuriy Petrovskiy
Una cosa a tener en cuenta: lo que está mostrando son los máximos, que pueden ser "valores atípicos". Creo que el paquete R alphahullfunciona de manera similar a encontrar el casco convexo, pero le permite ajustarlo hacia adentro / hacia afuera para intentar hacer algo como intervalos de confianza.
Wayne
@Wayne, un casco alfa no es un intervalo de confianza (de ninguna manera imaginable). Consulte esta pregunta de gis.se para obtener una breve descripción y algunas referencias de lo que es un casco alfa. Tal vez esté pensando en elipses de confianza bivariadas, o tal vez incluso en diagramas de bolsas (diagramas de caja bivariados para identificar valores atípicos).
Andy W

Respuestas:

33

Al buscar en Google, encontré el sitio web de Gota Morota, que ya tiene un ejemplo de esto en su sitio web . A continuación se muestra ese ejemplo extendido a sus datos.

enter image description here

library(ggplot2)
work <- "E:\\Forum_Post_Stuff\\convex_hull_ggplot2"
setwd(work)

#note you have some missing data
mydata <- read.table(file = "emD71JT5.txt",header = TRUE, fill = TRUE)
nomissing <- na.omit(mydata) #chull function does not work with missing data

#getting the convex hull of each unique point set
df <- nomissing
find_hull <- function(df) df[chull(df$eff, df$man), ]
hulls <- ddply(df, "issue", find_hull)

plot <- ggplot(data = nomissing, aes(x = eff, y = man, colour=issue, fill = issue)) +
geom_point() + 
geom_polygon(data = hulls, alpha = 0.5) +
labs(x = "Efficiency", y = "Mandate")
plot
Andy W
fuente
Gracias, revisaré el código en consecuencia. Desafortunadamente, su archivo de imagen no parece cargarse aquí, pero el código está allí.
p.
@Fr. , ¿Cuál es el problema exactamente?
Andy W
@AndyW Desafortunadamente, el código no admite valores perdidos, y no encontré una manera de modificarlo para hacerlo.
p.
@Fr., ¿Cómo exactamente quiere que se manejen los valores de datos perdidos además de eliminar esas observaciones? Cualquier técnica de imputación razonable daría como resultado que los puntos estén dentro de los cascos convexos de las observaciones no faltantes.
Andy W
@AndyW Quiero decir que NAmatan la chullfunción. Esperaría que simplemente lo ignore, pero falla al hacerlo y no encontré una manera na.omit()de hacerlo funcionar. Estoy seguro de que es posible, simplemente no tengo las habilidades de piratería informática para ir más allá de la solución anterior.
p.
8

Si entiendo tu problema, estás buscando el casco convexo de healthy de unemployment. Probablemente hay varios paquetes para hacer esto en R, uno de los cuales es paquete geometry. Me imagino que los puntos están ordenados en orden alrededor del perímetro, pero tendrías que verificar eso.

EDITAR: Aquí hay un ejemplo, que no usa ggplot, pero espero que sea útil. El ejemplo en la chulldocumentación parece estar equivocado, lo que podría estar desconcertando:

X <- matrix(rnorm(2000), ncol = 2)
X.chull <- chull (X)
X.chull <- c(X.chull, X.chull[1])
plot (X)
lines (X[X.chull,])

EDITAR 2: OK, aquí hay algo usando ggplot2. Nos convertimos Xen a data.framecon variables xy y. Luego:

library(ggplot2)
X <- as.data.frame(X)
hull <- chull(X)
hull <- c(hull, hull[1])
ggplot(X, aes(x=x, y=y)) + geom_polygon(data=X[hull,], fill="red") + geom_point()

Tenga en cuenta que geom_pointestá usando los datos ( X) y aes del ggplot, mientras que lo estoy anulando en el geom_polygon.

Para obtenerlo completamente, necesitaría poner la x e y para el casco para ambos problemas bar, utilizando una tercera columna issuepara diferenciarlos.

Wayne
fuente
Correcto sobre el casco convexo. He intentado usar chullpara generar el casco convexo pero no he podido usar los resultados con ggplot2.
p.
@Fr .: He hecho una edición rápida de mi respuesta. Vea si eso lo pone en el camino correcto.
Wayne
Puedo ver cómo funciona por sí solo, pero me pregunto cómo obtener esa última línea ggplot2.
p.
@Fr .: OK, ¿qué tal ahora?
Wayne
¡Funcionó! Gracias. Tuve que agregar na.omitpara deshacerme de NA que deja chullde funcionar. Gracias de nuevo.
p.
5

A partir de esta tarde, he incluido la chullfunción dentro de un paquete R como una geom_convexhullfunción.

Una vez que se carga el paquete, se puede usar como cualquier otra geom, en su caso debería ser algo como:

ggplot(d, aes(man, eff, colour=issue, fill=issue)) + 
  geom_convexhull(alpha=.5) + 
  geom_point() + 
  labs(x = "Efficiency", y = "Mandate"))

El paquete está disponible en github: https://github.com/cmartin/ggConvexHull

Charles Martin
fuente
¡Muchas gracias por esto! Me estaba frustrando por la salida no deseada cuando intentaba aplicar chullun factor de agrupación hasta que encontré esto.
jogall