如何在R中覆盖密度图?


81

我想在同一设备上用R覆盖2个密度图。我该怎么做?我在网上搜索,但没有找到任何明显的解决方案。

我的想法是从文本文件(列)中读取数据,然后使用

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

还是本着这种精神。

Answers:


92

使用lines了第二个:

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

但是,请确保第一幅图的范围合适。


9
+1当两个密度的范围不同并且第二条曲线不符合绘图限制时,您可能需要稍微复杂一点的东西。然后,您可以在绘制之前计算密度,并ylim使用range(dens1$y, dens2$y)wheredens1dens2是包含两个密度估计对象的对象来计算合适的密度。ylim在呼叫中使用此功能plot()
加文·辛普森

2
您可能还需要区分这两行。设置线宽(lwd),线型(lty)或线色(col)应该可以帮助您。届时,您还可以考虑使用legend()
nullglob

@Gavin如果OP正在读取文件,我将构造一个复杂的函数来读取数据(apply,lapply),查找所有数据集的范围,将默认范围设置为所有范围的最大范围,然后绘制(线条)的密度。
RomanLuštrik,2011年

50

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)

在此处输入图片说明


8
OP的data.frame首先需要熔化为长格式:ggplot (melt (MyData), mapping = aes (fill = variable, x = value)) + geom_density (alpha = .5)
cbeleites对SX不满意,2011年

1
不错的情节。什么是“ dat2” ...?什么是“融化”(找不到命令)?
Erik Aronesty

@ErikAronesty-您现在猜想和我一样好,我两年前回答了!我推测dat我的环境中还有另一个对象被命名为dat2...我提供的模拟数据可以像广告中那样工作。该melt()命令来自package reshape2。早在2011年,它reshape2是在加载时自动加载的ggplot2,但现在不再如此,因此您需要library(reshape2)单独进行操作。
Chase

21

添加照顾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))

这使:

在此处输入图片说明


我喜欢这个示例,但是如果您的数据列包含NA值,则该列将不起作用。我不确定如何修改代码,但这将很有用
雏菊

1
@daisy将此行更改dens <- apply(myData, 2, density)dens <- apply(myData, 2, density, na.rm=TRUE),它应该可以工作。
KarolisKoncevičius17年

12

为了提供完整的答案,这是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"))

产生如下图: 在此处输入图片说明


没有创建新的data.framedensityplot(~rnorm(100)+rnorm(100, 10, 5), plot.points=FALSE, ref=TRUE, auto.key = list(space = "right"))。或用于OP数据densityplot(~Column1+Column2, data=myData)
马雷克(Marek)

6

这就是我在基础中做的方式(实际上在第一个答案注释中提到过,但是我将在此处显示完整的代码,包括图例,因为我尚无法注释...)

首先,您需要从密度图中获取有关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"))

3

我以上面的格子示例为例,并做了一个漂亮的函数。可能有更好的方法来通过熔体/浇铸进行重塑。(如果有改进,请评论或编辑。)

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

2

您可以使用该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()

在此处输入图片说明


2

每当出现轴限制不匹配的问题时,都应base使用图形中的正确工具matplot。关键是要利用fromto参数density.default。有点骇人听闻,但介绍自己却相当简单:

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,...)。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.