在两点之间着色一个核密度图。

时间:2021-09-29 22:47:39

I frequently use kernel density plots to illustrate distributions. These are easy and fast to create in R like so:

我经常使用内核密度图来说明分布。这些在R中创建起来既简单又快速:

set.seed(1)
draws <- rnorm(100)^2
dens <- density(draws)
plot(dens)
#or in one line like this: plot(density(rnorm(100)^2))

Which gives me this nice little PDF:

这给了我一个很好的PDF:

在两点之间着色一个核密度图。

I'd like to shade the area under the PDF from the 75th to 95th percentiles. It's easy to calculate the points using the quantile function:

我想把PDF下面的区域从第75到第95百分位数进行阴影处理。用分位数函数计算点很容易:

q75 <- quantile(draws, .75)
q95 <- quantile(draws, .95)

But how do I shade the the area between q75 and q95?

但是我如何在q75和q95之间的区域着色呢?

4 个解决方案

#1


71  

With the polygon() function, see its help page and I believe we had similar questions here too.

使用polygon()函数,请参阅它的帮助页面,我相信我们在这里也有类似的问题。

You need to find the index of the quantile values to get the actual (x,y) pairs.

你需要找到分位数的索引来得到实际的(x,y)对。

Edit: Here you go:

编辑:给你:

x1 <- min(which(dens$x >= q75))  
x2 <- max(which(dens$x <  q95))
with(dens, polygon(x=c(x[c(x1,x1:x2,x2)]), y= c(0, y[x1:x2], 0), col="gray"))

Output (added by JDL)

添加的输出(金)

在两点之间着色一个核密度图。

#2


66  

Another solution:

另一个解决方案:

dd <- with(dens,data.frame(x,y))
library(ggplot2)
qplot(x,y,data=dd,geom="line")+
  geom_ribbon(data=subset(dd,x>q75 & x<q95),aes(ymax=y),ymin=0,
              fill="red",colour=NA,alpha=0.5)

Result: 在两点之间着色一个核密度图。

结果:

#3


20  

An expanded solution:

一个扩展的解决方案:

If you wanted to shade both tails (copy & paste of Dirk's code) and use known x values:

如果你想把两条尾巴都遮住(复制和粘贴Dirk代码),并使用已知的x值:

set.seed(1)
draws <- rnorm(100)^2
dens <- density(draws)
plot(dens)

q2     <- 2
q65    <- 6.5
qn08   <- -0.8
qn02   <- -0.2

x1 <- min(which(dens$x >= q2))  
x2 <- max(which(dens$x <  q65))
x3 <- min(which(dens$x >= qn08))  
x4 <- max(which(dens$x <  qn02))

with(dens, polygon(x=c(x[c(x1,x1:x2,x2)]), y= c(0, y[x1:x2], 0), col="gray"))
with(dens, polygon(x=c(x[c(x3,x3:x4,x4)]), y= c(0, y[x3:x4], 0), col="gray"))

Result:

结果:

在两点之间着色一个核密度图。

#4


17  

This question needs a lattice answer. Here's a very basic one, simply adapting the method employed by Dirk and others:

这个问题需要一个巧妙的答案。这里有一个非常基本的方法,简单地采用Dirk和其他人使用的方法:

#Set up the data
set.seed(1)
draws <- rnorm(100)^2
dens <- density(draws)

#Put in a simple data frame   
d <- data.frame(x = dens$x, y = dens$y)

#Define a custom panel function;
# Options like color don't need to be hard coded    
shadePanel <- function(x,y,shadeLims){
    panel.lines(x,y)
    m1 <- min(which(x >= shadeLims[1]))
    m2 <- max(which(x <= shadeLims[2]))
    tmp <- data.frame(x1 = x[c(m1,m1:m2,m2)], y1 = c(0,y[m1:m2],0))
    panel.polygon(tmp$x1,tmp$y1,col = "blue")
}

#Plot
xyplot(y~x,data = d, panel = shadePanel, shadeLims = c(1,3))

在两点之间着色一个核密度图。

#1


71  

With the polygon() function, see its help page and I believe we had similar questions here too.

使用polygon()函数,请参阅它的帮助页面,我相信我们在这里也有类似的问题。

You need to find the index of the quantile values to get the actual (x,y) pairs.

你需要找到分位数的索引来得到实际的(x,y)对。

Edit: Here you go:

编辑:给你:

x1 <- min(which(dens$x >= q75))  
x2 <- max(which(dens$x <  q95))
with(dens, polygon(x=c(x[c(x1,x1:x2,x2)]), y= c(0, y[x1:x2], 0), col="gray"))

Output (added by JDL)

添加的输出(金)

在两点之间着色一个核密度图。

#2


66  

Another solution:

另一个解决方案:

dd <- with(dens,data.frame(x,y))
library(ggplot2)
qplot(x,y,data=dd,geom="line")+
  geom_ribbon(data=subset(dd,x>q75 & x<q95),aes(ymax=y),ymin=0,
              fill="red",colour=NA,alpha=0.5)

Result: 在两点之间着色一个核密度图。

结果:

#3


20  

An expanded solution:

一个扩展的解决方案:

If you wanted to shade both tails (copy & paste of Dirk's code) and use known x values:

如果你想把两条尾巴都遮住(复制和粘贴Dirk代码),并使用已知的x值:

set.seed(1)
draws <- rnorm(100)^2
dens <- density(draws)
plot(dens)

q2     <- 2
q65    <- 6.5
qn08   <- -0.8
qn02   <- -0.2

x1 <- min(which(dens$x >= q2))  
x2 <- max(which(dens$x <  q65))
x3 <- min(which(dens$x >= qn08))  
x4 <- max(which(dens$x <  qn02))

with(dens, polygon(x=c(x[c(x1,x1:x2,x2)]), y= c(0, y[x1:x2], 0), col="gray"))
with(dens, polygon(x=c(x[c(x3,x3:x4,x4)]), y= c(0, y[x3:x4], 0), col="gray"))

Result:

结果:

在两点之间着色一个核密度图。

#4


17  

This question needs a lattice answer. Here's a very basic one, simply adapting the method employed by Dirk and others:

这个问题需要一个巧妙的答案。这里有一个非常基本的方法,简单地采用Dirk和其他人使用的方法:

#Set up the data
set.seed(1)
draws <- rnorm(100)^2
dens <- density(draws)

#Put in a simple data frame   
d <- data.frame(x = dens$x, y = dens$y)

#Define a custom panel function;
# Options like color don't need to be hard coded    
shadePanel <- function(x,y,shadeLims){
    panel.lines(x,y)
    m1 <- min(which(x >= shadeLims[1]))
    m2 <- max(which(x <= shadeLims[2]))
    tmp <- data.frame(x1 = x[c(m1,m1:m2,m2)], y1 = c(0,y[m1:m2],0))
    panel.polygon(tmp$x1,tmp$y1,col = "blue")
}

#Plot
xyplot(y~x,data = d, panel = shadePanel, shadeLims = c(1,3))

在两点之间着色一个核密度图。