2015-12-14 14 views
7

ggplot2 może stworzyć bardzo atrakcyjną wypełniony skrzypce działki:Działka skrzypiec ggplot2: wypełnić tylko centralę 95%?

ggplot() + geom_violin(data=data.frame(x=1, y=rnorm(10^5)), 
    aes(x=x, y=y), fill='gray90', color='black') + 
    theme_classic() 

chciałbym ograniczyć do wypełnienia centralnego 95% rozkładu, jeśli to możliwe, pozostawiając konspekt nienaruszone. Czy ktoś ma sugestie, jak to osiągnąć?

Odpowiedz

6

Czy to robi, co chcesz? Wymaga przetwarzania danych i rysowania dwóch skrzypiec.

set.seed(1) 
dat <- data.frame(x=1, y=rnorm(10^5)) 

#calculate for each point if it's central or not 
dat_q <- quantile(dat$y, probs=c(0.025,0.975)) 
dat$central <- dat$y>dat_q[1] & dat$y < dat_q[2] 

#plot; one'95' violin and one 'all'-violin with transparent fill. 
p1 <- ggplot(data=dat, aes(x=x,y=y)) + 
    geom_violin(data=dat[dat$central,], color="transparent",fill="gray90")+ 
    geom_violin(color="black",fill="transparent")+ 

    theme_classic() 

enter image description here

Edit: zaokrąglone krawędzie mi nie przeszkadzało, więc o to drugie podejście. Gdybym to robił, chciałbym mieć proste linie. Więc zrobiłem trochę bawi się z gęstością (czego Działki są oparte na skrzypce)

d_y <- density(dat$y) 

right_side <- data.frame(x=d_y$y, y=d_y$x) #note flip of x and y, prevents coord_flip later 
right_side$central <- right_side$y > dat_q[1]&right_side$y < dat_q[2] 

#add the 'left side', this entails reversing the order of the data for 
#path and polygon 
#and making x negative 
left_side <- right_side[nrow(right_side):1,] 
left_side$x <- 0 - left_side$x 

density_dat <- rbind(right_side,left_side) 


p2 <- ggplot(density_dat, aes(x=x,y=y)) + 
    geom_polygon(data=density_dat[density_dat$central,],fill="red")+ 
    geom_path() 


p2 

enter image description here

+0

Ach, po prostu mnie pokonać! – Axeman

+1

@Axeman Wielki umysł myśli podobnie? Dodałem drugie podejście. – Heroka

+0

@Heroka, to jest świetne! Jak się domyślacie, natknąłem się na twoje pierwsze podejście, ale nie byłem usatysfakcjonowany. Twoje drugie podejście jest dokładnie tym, czego chciałem. Wielkie dzięki! – dewarrn1

2

Wystarczy dokonać wyboru w pierwszej kolejności. Dowód koncepcji:

df1 <- data.frame(x=1, y=rnorm(10^5)) 
df2 <- subset(df1, y > quantile(df1$y, 0.025) & y < quantile(df1$y, 0.975)) 

ggplot(mapping = aes(x = x, y = y)) + 
    geom_violin(data = df1, aes(fill = '100%'), color = NA) + 
    geom_violin(data = df2, aes(fill = '95%'), color = 'black') + 
    theme_classic() + 
    scale_fill_grey(name = 'level') 

enter image description here