Como desenhar polígonos puros em torno das regiões do gráfico de dispersão no ggplot2 [fechado]

32

Como adiciono um polígono puro em torno de um grupo de pontos em um gráfico de dispersão? Estou usando o ggplot2, mas estou decepcionado com os resultados de geom_polygon.

O conjunto de dados está , como um arquivo de texto delimitado por tabulação. O gráfico abaixo mostra duas medidas de atitudes em relação à saúde e ao desemprego em vários países:

gráfico de dispersão com density2d

Gostaria de mudar geom_density2dpara o menos sofisticado, mas empiricamente mais correto geom_polygon. O resultado em dados não classificados é inútil:

insira a descrição da imagem aqui

Como faço para desenhar polígonos 'puros' que se comportam como caminhos de contorno em torno dos valores de min-max yx? Tentei classificar os dados sem sucesso.

Código:

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

O dobjeto é obtido com este arquivo CSV .

Solução:

Agradecimentos a Wayne , Andy W e outros por suas dicas! Os dados, código e gráficos foram publicados no GitHub . O resultado fica assim:

resultado

Pe.
fonte
6
O termo que você pode estar procurando é o casco convexo dos pontos (ou potencialmente o casco alfa). Você deve encontrar uma função R para calculá-las e, em seguida, adicioná-las como camadas ao gráfico.
Andy W
Obrigado por apontar a terminologia correta! Eu não conseguiram uso ?chullcom ggplot2até agora. Não tenho certeza se estou codificando corretamente e espero que alguém já tenha feito isso.
pe.
Você poderia adicionar seu código R à pergunta?
Yuriy Petrovskiy
Uma coisa a observar: o que você está exibindo são os máximos, que podem ser "discrepantes". Acredito que o pacote R alphahullfuncione de maneira semelhante à localização do casco convexo, mas permite que você o ajuste para dentro / fora para tentar fazer algo como intervalos de confiança.
22712 Wayne
@Wayne, um casco alfa não é um intervalo de confiança (de qualquer forma imaginável). Veja esta questão do gis.se para uma breve descrição e algumas referências sobre o que é um casco alfa. Talvez você esteja pensando em elipses de confiança bivariadas, ou até mesmo em lotes (bagplots bi-variados para identificar valores extremos).
Andy W

Respostas:

33

Com algumas pesquisas, me deparei com o site da Gota Morota, que já tem um exemplo disso em seu site . Abaixo está o exemplo estendido aos seus dados.

insira a descrição da imagem aqui

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
fonte
Obrigado, revisarei o código adequadamente. Infelizmente, seu arquivo de imagem não parece carregar aqui, mas o código está lá.
pe.
@Fr. Qual é exatamente o problema?
21712 Andy W no dia
@ AndyW Infelizmente, o código não suporta valores ausentes, e eu não encontrei uma maneira de ajustá-lo para fazer isso.
pe.
@Fr., Como exatamente você deseja que os valores de dados ausentes sejam tratados além de eliminar essas observações? Qualquer técnica razoável de imputação resultaria em pontos dentro dos cascos convexos das observações não perdidas.
Andy W
@ AndyW quero dizer que NAa chullfunção de matar . Eu esperaria que isso fosse ignorado, mas falha ao fazê-lo e não encontrei uma maneira de usá na.omit()-lo. Tenho certeza de que é possível, simplesmente não tenho as habilidades de hackers para ir além da solução anterior.
pe.
8

Se eu entendo o seu problema, você está procurando o casco convexo de healthe de unemployment. Provavelmente existem vários pacotes para fazer isso no R, um dos quais é o pacote geometry. Eu imagino que os pontos são classificados em ordem em torno do perímetro, mas você teria que verificar isso.

EDIT: Aqui está um exemplo, que não usa ggplot, mas espero que seja útil. O exemplo na chulldocumentação parece estar errado, o que pode estar deixando você louco:

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

EDIT 2: OK, aqui está algo usando o ggplot2. Transformamos Xem a data.framecom variáveis xe y. Então:

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

Note que ele geom_pointestá usando os dados ( X) e aes do ggplot, enquanto eu estou substituindo-o no geom_polygon.

Para obtê-lo completamente, você precisará colocar xey no casco dos dois problemas bar, usando uma terceira coluna issuepara diferenciá-los.

Wayne
fonte
Correto sobre o casco convexo. Eu tentei usar chullpara gerar o casco convexo, mas não consegui usar os resultados com ggplot2.
pe.
@Fr .: Eu fiz uma edição rápida da minha resposta. Veja se isso o coloca no caminho certo.
Wayne
Eu posso ver como funciona por conta própria, mas me pergunto como obter essa última linha ggplot2.
pe.
@Fr .: OK, e agora?
Wayne
Funcionou! Obrigado. Eu tive que adicionar na.omitpara me livrar de NA que para chullde funcionar. Obrigado novamente.
pe.
5

A partir desta tarde, envolvi a chullfunção dentro de um pacote R como uma geom_convexhullfunção.

Depois que o pacote é carregado, ele pode ser usado como qualquer outro geom; no seu caso, deve ser algo como:

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

O pacote está disponível no github: https://github.com/cmartin/ggConvexHull

Charles Martin
fonte
Muito obrigado por isso! Eu estava ficando frustrado com a saída indesejada ao tentar aplicar chullum fator de agrupamento até encontrar isso.
jogall 10/02