2017-09-29 118 views
0

數據描述了兩個村莊Villariba和Villabajo之間長達4000多米長的道路上樹木的商品分佈(蘋果和香蕉)。數據已經被分類(即每500米提供一個總結),或者提供了大量的地點誤差,因此500米的分類是很自然的。我們想要通過內核平滑處理並將它們繪製成平滑的後分布分佈。有兩種明顯的方法可以在ggplot2包中執行此操作。首先讀取數據(長格式)。R:使用ggplot2平滑處理數據圖中的binned數據

library(ggplot2) 
databas<-read.csv(text="dist,stuff,val 
500,apples,10 
1250,apples,25 
1750,apples,55 
2250,apples,45 
2750,apples,25 
3250,apples,10 
3750,apples,5 
500,bananas,7 
1250,bananas,14 
1750,bananas,20 
2250,bananas,17 
2750,bananas,10 
3250,bananas,30 
3750,bananas,20") 

的第一次嘗試是一個無聊的barplot與geom_col()。接下來,我們可以分別使用密度圖(geom_density())和平滑曲線(stat_smooth()或等效geom_smooth())中包含的兩個ggplot2工具。該三種方式實現如下:

p1<-ggplot(databas,aes(dist,val,fill=stuff,alpha=0.5))+geom_col(alpha=0.5,position="dodge") 
    p2<-ggplot(databas,aes(dist,val,fill=stuff))+stat_smooth(aes(y=val,x=dist),method="gam",se=FALSE,formula=y~s(x,k=7)) 
    p3<-ggplot(databas,aes(dist,val,fill=stuff,alpha=0.5))+geom_density(stat="identity") 

library(gridExtra) 
grid.arrange(p1,p2,p3,nrow=3) 

three plots with density smoothing in ggplot2

有每一個方法的不足之處。疊加密度圖(底部圖)是最想要的設計,但是選項stat="identity"(因爲數據是分級的)可防止創建精美的平滑分佈,就像通常一樣。 stat_smooth()選項提供幾乎優秀的曲線,但這些只是曲線。那麼,如何將來自密度圖的着色和平滑函數的平滑結合起來呢?這是爲了平滑geom_density()中的數據,還是在stat_smooth()曲線下用半透明顏色填充空間?

回答

2

如果你喜歡你gam配合,你可以使用stat = "smooth"geom_ribbon繪製曲線。訣竅是將ymin設置爲0並將ymax設置爲..y..,這是由預測線stat_smooth創建的特殊變量。

ggplot(databas, aes(x = dist, y = val, fill = stuff)) + 
    geom_ribbon(stat = "smooth", aes(ymin = 0, ymax = ..y..), alpha = .5, 
       method = "gam", se=FALSE, formula = y ~ s(x, k = 7)) 

enter image description here

2

這裏有一種方法:

library(ggplot2) 
p2 <- ggplot(databas, aes(dist ,val ,fill = stuff)) + stat_smooth(aes(y = val,x = dist), method = "gam",se = FALSE,formula = y ~ s(x, k = 7)) 

提取曲線與ggplot_build

p2_build = ggplot_build(p2) 
p2_fill <- data_frame(
    x = p2_build$data[[1]]$x, 
    y = p2_build$data[[1]]$y, 
    group = factor(p2_build$data[[1]]$group, levels = c(1,2), labels = c("apples","bananas"))) 

加彩與geom_area

p2 + geom_area(data = p2_fill[p2_fill$group == "apples", ], 
        aes(x=x, y=y), fill = "red", alpha = 0.2)+ 
    geom_area(data = p2_fill[p2_fill$group == "bananas", ], 
      aes(x=x, y=y), fill = "blue", alpha = 0.2) 

enter image description here

完整的答案:

ggplot(databas, aes(dist, val, color = stuff))+ 
    stat_smooth(aes(y = val,x = dist), method = "gam",se = FALSE, formula = y ~ s(x, k = 7))+ 
    geom_area(data = p2_fill[p2_fill$group == "apples", ], 
      aes(x=x, y=y), fill = "#F8766D", alpha = 0.2, inherit.aes = F)+ 
    geom_area(data = p2_fill[p2_fill$group == "bananas", ], 
      aes(x=x, y=y), fill = "#00BFC4", alpha = 0.2, inherit.aes = F)+ 
    theme_classic() 

enter image description here