2015-07-01 14 views
7

Mam wykresy rozrzutu danych 2D z dwóch kategorii. Chcę dodać linie gęstości dla każdego wymiaru - nie poza działką (porównaj Scatterplot with marginal histograms in ggplot2), ale bezpośrednio na powierzchni kreślarskiej. Mogę to dla wymiaru osi x, tak:ggplot2: dodaj warunkowe krzywe gęstości opisujące oba wymiary wykresu rozrzutu

set.seed(123) 
dim1 <- c(rnorm(100, mean=1), rnorm(100, mean=4)) 
dim2 <- rnorm(200, mean=1) 
cat <- factor(c(rep("a", 100), rep("b", 100))) 
mydf <- data.frame(cbind(dim2, dim1, cat)) 
ggplot(data=mydf, aes(x=dim1, y=dim2, colour=as.factor(cat))) + 
    geom_point() + 
    stat_density(aes(x=dim1, y=(-2+(..scaled..))), 
    position="identity", geom="line") 

Wygląda to tak:

enter image description here

Ale chcę analogiczna parę krzywych gęstości działa pionowo, pokazujący rozkład punktów w wymiarze y. Wypróbowałem

stat_density(aes(y=dim2, x=0+(..scaled..))), position="identity", geom="line) 

ale otrzymałem błąd "stat_density wymaga następujących brakujących estetyki: x".

Wszelkie pomysły? Dzięki

+1

dodałem swój (oczekuje) działka. To wygląda na trudne. Zastanawiam się, czy 'coord_flip' jest przydatny tutaj – C8H10N4O2

+1

Jest to interesujące, chociaż nie jest to, czego szukasz:' ggplot (data = mydf, aes (x = dim1, y = dim2, color = as.factor (cat))) + stat_density2d() ' – C8H10N4O2

Odpowiedz

8

Możesz uzyskać gęstości dim2 zmiennych. Następnie odwróć osie i umieść je w nowym pliku data.frame. Potem po prostu wykreśla je na drugim wykresie.

p <- ggplot(data=mydf, aes(x=dim1, y=dim2, colour=as.factor(cat))) + 
    geom_point() + 
    stat_density(aes(x=dim1, y=(-2+(..scaled..))), 
       position="identity", geom="line") 

stuff <- ggplot_build(p) 
xrange <- stuff[[2]]$ranges[[1]]$x.range # extract the x range, to make the new densities align with y-axis 

## Get densities of dim2 
ds <- do.call(rbind, lapply(unique(mydf$cat), function(lev) { 
    dens <- with(mydf, density(dim2[cat==lev])) 
    data.frame(x=dens$y+xrange[1], y=dens$x, cat=lev) 
})) 

p + geom_path(data=ds, aes(x=x, y=y, color=factor(cat))) 

enter image description here

+1

Bardzo ładne rozwiązanie. Kicking siebie za nie używanie 'gęstości' – C8H10N4O2

+0

dzięki, wygląda na to, że ggplot może nieco skalować wartości y gęstości? Twoje krzywe po coordin_flip wyglądają nieco "wyższym". – jenesaisquoi

+0

Jeśli oryginalny zestaw danych miał czynnik (4-sposób, powiedzmy), którego używałem do facet_grid, wszelkie przemyślenia dotyczące modyfikowania pobierania gęstości do.call, aby wyciągnąć te dane? –

2

Dotychczas mogę produkować:

distrib_horiz <- stat_density(aes(x=dim1, y=(-2+(..scaled..))), 
           position="identity", geom="line") 

ggplot(data=mydf, aes(x=dim1, y=dim2, colour=as.factor(cat))) + 
    geom_point() + distrib_horiz 

enter image description here

oraz:

distrib_vert <- stat_density(data=mydf, aes(x=dim2, y=(-2+(..scaled..))), 
          position="identity", geom="line") 

ggplot(data=mydf, aes(x=dim2, y=dim1, colour=as.factor(cat))) + 
    geom_point() + distrib_vert + coord_flip() 

enter image description here

Ale łącząc je okazuje się trudne.

+0

zachowanie stat_density w strukturze danych wydaje się fajnym początkiem (jeśli można by z niego narysować linię, ggplot nie musiałby wiedzieć, skąd pochodzą x, y). Ale nie jestem pewien, jak uzyskać dostęp do danych gęstości. –

1

Do tej pory mam tylko częściowe rozwiązanie, ponieważ nie udało mi się uzyskać pionowej linii stat_density dla każdej kategorii, tylko dla całego zestawu. Może to jednak pomoże jako punkt wyjścia do znalezienia lepszego rozwiązania. Moja sugestia polega na wypróbowaniu funkcji ggMarginal() z pakietu ggExtra.

p <- ggplot(data=mydf, aes(x=dim1, y=dim2, colour=as.factor(cat))) + 
    geom_point() + stat_density(aes(x=dim1, y=(-2+(..scaled..))), 
      position="identity", geom="line") 
library(ggExtra) 
ggMarginal(p,type = "density", margins = "y", size = 4) 

To, co otrzymujemy: enter image description here

wiem, że to nie jest idealne, ale być może jest to krok w kierunku pomocnym. Przynajmniej mam taką nadzieję. Czekamy na inne odpowiedzi.

Powiązane problemy