Jak narysować czyste wielokąty wokół regionów wykresu rozrzutu w ggplot2 [zamknięte]

32

Jak dodać zgrabny wielokąt wokół grupy punktów na wykresie rozrzutu? Korzystam z ggplot2, ale jestem rozczarowany wynikami geom_polygon.

Zestaw danych jest tam , jako plik tekstowy rozdzielany tabulatorami. Poniższy wykres pokazuje dwie miary postaw wobec zdrowia i bezrobocia w wielu krajach:

wykres rozrzutu z gęstością2d

Chciałbym przejść z geom_density2dmniej fantazyjnych, ale bardziej empirycznych geom_polygon. Wynik nieposortowanych danych jest nieprzydatny:

wprowadź opis zdjęcia tutaj

Jak narysować „czyste” wielokąty, które zachowują się jak ścieżki konturu wokół wartości min-maks. Yx? Próbowałem posortować dane bezskutecznie.

Kod:

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

dObiekt uzyskuje z tego pliku CSV .

Rozwiązanie:

Podziękowania dla Wayne'a , Andy'ego W i innych za ich wskazówki! Dane, kod i wykresy zostały opublikowane w GitHub . Wynik wygląda następująco:

wynik

Ks.
źródło
6
Określenie, którego możesz szukać, to wypukły kadłub punktów (lub potencjalnie kadłub alfa). Powinieneś być w stanie znaleźć funkcję R do ich obliczenia, a następnie być w stanie dodać je jako warstwy do wykresu.
Andy W
Dziękujemy za wskazanie poprawnej terminologii! Do tej pory nie korzystałem ?chullz ggplot2. Nie jestem pewien, czy dobrze go koduję i mam nadzieję, że ktoś już to zrobił.
ks.
Czy możesz dodać swój kod R do pytania?
Jurij Pietrowski
Należy zwrócić uwagę na jedno: wyświetlane są maksima, które mogą być „wartościami odstającymi”. Wierzę, że pakiet R alphahulldziała podobnie do znalezienia wypukłego kadłuba, ale pozwala dostosować go do wewnątrz / na zewnątrz, aby spróbować zrobić coś takiego jak przedziały ufności.
Wayne
@Wayne, kadłub alfa nie jest przedziałem ufności (w jakikolwiek sposób można sobie wyobrazić). Zobacz to pytanie gis.se, aby uzyskać krótki opis i odniesienia do tego, czym jest kadłub alfa. Być może twoje myślenie o dwuwymiarowych elipsach zaufania, a może nawet bagploty (bi-zmienne wykresy pudełkowe do identyfikowania wartości odstających).
Andy W

Odpowiedzi:

33

Z pewnym googlowaniem natknąłem się na stronę Gota Morota, która ma przykład takiego działania już na swojej stronie . Poniżej znajduje się przykład rozszerzony na twoje dane.

wprowadź opis zdjęcia tutaj

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.
źródło
Dzięki, odpowiednio zmienię kod. Niestety Twój plik obrazu nie wydaje się tutaj ładować, ale kod już istnieje.
ks.
@Fr. , Na czym dokładnie polega problem?
Andy W
@AndyW Niestety, kod nie obsługuje brakujących wartości i nie znalazłem sposobu na jego poprawienie.
ks.
@Fr., W jaki sposób chcesz wyeliminować brakujące dane, oprócz wyeliminowania tych obserwacji? Każda rozsądna technika imputacji spowodowałaby, że punkty znajdowałyby się wewnątrz wypukłych kadłubów nie brakujących obserwacji.
Andy W
@ AndyW Mam na myśli, że NAzabij chullfunkcję. Spodziewałbym się, że to po prostu zignoruje, ale to się nie udaje i nie znalazłem sposobu, aby na.omit()to zrobić. Jestem pewien, że to możliwe, po prostu nie mam umiejętności hakerskich, aby wyjść poza poprzednie rozwiązanie.
ks.
8

Jeśli rozumiem problem, szukasz wypukłej kadłubie healthi unemployment. Prawdopodobnie istnieje kilka pakietów, aby to zrobić w R, z których jeden to pakiet geometry. Wyobrażam sobie, że punkty są sortowane w kolejności wokół obwodu, ale trzeba to sprawdzić.

EDYCJA: Oto przykład, który nie używa ggplot, ale mam nadzieję, że będzie przydatny. Przykład w chulldokumentacji wydaje się błędny, co może cię wyrzucać:

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

EDYCJA 2: OK, oto coś przy użyciu ggplot2. Zmieniamy Xsię w data.framezmienne xi y. Następnie:

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

Zauważ, że geom_pointużywa danych ( X) i aes z ggplot, podczas gdy nadpisuję je w geom_polygon.

Aby uzyskać go w pełni, musisz umieścić xiy dla kadłuba dla obu problemów bar, używając trzeciej kolumny, issueaby je rozróżnić.

Wayne
źródło
Prawidłowo o wypukłym kadłubie. Próbowałem użyć chulldo wygenerowania wypukłego kadłuba, ale nie udało mi się użyć wyników ggplot2.
ks.
@Fr .: Zrobiłem szybką edycję mojej odpowiedzi. Sprawdź, czy to stawia Cię na właściwej drodze.
Wayne
Widzę, jak działa samodzielnie, ale zastanawiam się, jak uzyskać tę ostatnią linię ggplot2.
ks.
@Fr .: OK, a co teraz?
Wayne
Zadziałało! Dzięki. Musiałem dodać, na.omitaby pozbyć się NA, które przestają chulldziałać. Dzięki jeszcze raz.
ks.
5

Od tego popołudnia zawarłem tę chullfunkcję w pakiecie R jakogeom_convexhull funkcję.

Po załadowaniu pakiet może być używany jako dowolny inny geom, w twoim przypadku powinno to być coś takiego:

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

Pakiet jest dostępny na github: https://github.com/cmartin/ggConvexHull

Charles Martin
źródło
Wielkie dzięki za to! Byłem sfrustrowany niepożądanymi efektami, gdy próbowałem zastosować chullczynnik grupujący, dopóki go nie znalazłem.
jogall,