簡體   English   中英

如何在R中疊加密度圖?

[英]How to overlay density plots in R?

我想用 R 在同一台設備上疊加 2 個密度圖。我該怎么做? 我在網上搜索,但沒有找到任何明顯的解決方案。

我的想法是從文本文件(列)中讀取數據,然后使用

plot(density(MyData$Column1))
plot(density(MyData$Column2), add=T)

或者本着這種精神的東西。

使用第二lines

plot(density(MyData$Column1))
lines(density(MyData$Column2))

不過,請確保第一個圖的限制是合適的。

ggplot2是另一個圖形包,它以一種非常巧妙的方式處理 Gavin 提到的范圍問題。 它還可以處理自動生成適當的圖例,並且在我看來,開箱即用的感覺通常更精致,手動操作更少。

library(ggplot2)

#Sample data
dat <- data.frame(dens = c(rnorm(100), rnorm(100, 10, 5))
                   , lines = rep(c("a", "b"), each = 100))
#Plot.
ggplot(dat, aes(x = dens, fill = lines)) + geom_density(alpha = 0.5)

在此處輸入圖片說明

添加處理 y 軸限制的基本圖形版本,添加顏色並適用於任意數量的列:

如果我們有一個數據集:

myData <- data.frame(std.nromal=rnorm(1000, m=0, sd=1),
                     wide.normal=rnorm(1000, m=0, sd=2),
                     exponent=rexp(1000, rate=1),
                     uniform=runif(1000, min=-3, max=3)
                     )

然后繪制密度:

dens <- apply(myData, 2, density)

plot(NA, xlim=range(sapply(dens, "[", "x")), ylim=range(sapply(dens, "[", "y")))
mapply(lines, dens, col=1:length(dens))

legend("topright", legend=names(dens), fill=1:length(dens))

這使:

在此處輸入圖片說明

只是為了提供一個完整的集合,這是 Chase 使用lattice的答案的一個版本:

dat <- data.frame(dens = c(rnorm(100), rnorm(100, 10, 5))
                   , lines = rep(c("a", "b"), each = 100))

densityplot(~dens,data=dat,groups = lines,
            plot.points = FALSE, ref = TRUE, 
            auto.key = list(space = "right"))

這產生了這樣的情節:在此處輸入圖片說明

這就是我在 base 中的做法(實際上在第一個答案評論中提到過,但我將在此處顯示完整代碼,包括圖例,因為我還不能評論......)

首先,您需要從密度圖中獲取 y 軸最大值的信息。 所以你需要首先分別計算密度

dta_A <- density(VarA, na.rm = TRUE)
dta_B <- density(VarB, na.rm = TRUE)

然后根據第一個答案繪制它們並為您剛剛獲得的 y 軸定義最小值和最大值。 (我將最小值設置為 0)

plot(dta_A, col = "blue", main = "2 densities on one plot"), 
     ylim = c(0, max(dta_A$y,dta_B$y)))  
lines(dta_B, col = "red")

然后在右上角添加圖例

legend("topright", c("VarA","VarB"), lty = c(1,1), col = c("blue","red"))

我拿上面的格子例子做了一個漂亮的函數。 可能有更好的方法通過熔化/鑄造重塑。 (如果您看到改進,請發表評論或編輯。)

multi.density.plot=function(data,main=paste(names(data),collapse = ' vs '),...){
  ##combines multiple density plots together when given a list
  df=data.frame();
  for(n in names(data)){
    idf=data.frame(x=data[[n]],label=rep(n,length(data[[n]])))
    df=rbind(df,idf)
  }
  densityplot(~x,data=df,groups = label,plot.points = F, ref = T, auto.key = list(space = "right"),main=main,...)
}

用法示例:

multi.density.plot(list(BN1=bn1$V1,BN2=bn2$V1),main='BN1 vs BN2')

multi.density.plot(list(BN1=bn1$V1,BN2=bn2$V1))

每當出現軸限制不匹配的問題時, base圖形中的正確工具是使用matplot 關鍵是利用fromto參數來傳遞給density.default 這有點hackish,但自己滾動相當簡單:

set.seed(102349)
x1 = rnorm(1000, mean = 5, sd = 3)
x2 = rnorm(5000, mean = 2, sd = 8)

xrng = range(x1, x2)

#force the x values at which density is
#  evaluated to be the same between 'density'
#  calls by specifying 'from' and 'to'
#  (and possibly 'n', if you'd like)
kde1 = density(x1, from = xrng[1L], to = xrng[2L])
kde2 = density(x2, from = xrng[1L], to = xrng[2L])

matplot(kde1$x, cbind(kde1$y, kde2$y))

描繪調用 matplot 的輸出的圖。觀察到兩條曲線,一條紅色,另一條黑色;黑色曲線比紅色曲線延伸得更高,而紅色曲線則“更胖”。

根據需要添加花里胡哨( matplot接受所有標准的plot / par參數,例如ltytypecollwd ,...)。

您可以使用ggjoy包。 假設我們有三個不同的beta分布,例如:

set.seed(5)
b1<-data.frame(Variant= "Variant 1", Values = rbeta(1000, 101, 1001))
b2<-data.frame(Variant= "Variant 2", Values = rbeta(1000, 111, 1011))
b3<-data.frame(Variant= "Variant 3", Values = rbeta(1000, 11, 101))


df<-rbind(b1,b2,b3)

您可以獲得三種不同的分布,如下所示:

library(tidyverse)
library(ggjoy)


ggplot(df, aes(x=Values, y=Variant))+
    geom_joy(scale = 2, alpha=0.5) +
    scale_y_discrete(expand=c(0.01, 0)) +
    scale_x_continuous(expand=c(0.01, 0)) +
    theme_joy()

在此處輸入圖片說明

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM