如何在ggplot中对密度曲线的一部分进行阴影处理(没有y轴数据)

18

我正在使用一组介于 0 到 1000 之间的随机数创建 R 中的密度曲线,并着色小于或等于特定值的部分。有很多解决方案涉及到 geom_areageom_ribbon,但它们都需要一个 y 值,而我没有(只是 1000 个数字的向量)。请问有什么办法可以做到这一点吗?

另外还有两个相关的问题:

  1. 对于累积分布函数是否也可以使用相同的方法(我目前正在使用 stat_ecdf 生成它),或者可以着色吗?
  2. 是否可以编辑 geom_vline 让它只延伸到密度曲线的高度而非整个 y 轴?

代码:(geom_area 是修改我找到的一些代码的失败尝试。如果手动设置 ymax,则只会得到占据整个图形的列,而不是曲线下面的面积)

set.seed(100)

amount_spent <- rnorm(1000,500,150)
amount_spent1<- data.frame(amount_spent)
rand1 <- runif(1,0,1000)
amount_spent1$pdf <- dnorm(amount_spent1$amount_spent)

mean1 <- mean(amount_spent1$amount_spent)

#density/bell curve
ggplot(amount_spent1,aes(amount_spent)) +
   geom_density( size=1.05, color="gray64", alpha=.5, fill="gray77") +
   geom_vline(xintercept=mean1, alpha=.7, linetype="dashed", size=1.1, color="cadetblue4")+
   geom_vline(xintercept=rand1, alpha=.7, linetype="dashed",size=1.1, color="red3")+
   geom_area(mapping=aes(ifelse(amount_spent1$amount_spent > rand1,amount_spent1$amount_spent,0)), ymin=0, ymax=.03,fill="red",alpha=.3)+
   ylab("")+ 
   xlab("Amount spent on lobbying (in Millions USD)")+
   scale_x_continuous(breaks=seq(0,1000,100))

3
在这种情况下,可能更容易在ggplot之外计算密度,或使用绘图的内部。如果p是你的基本密度图:d <- ggplot_build(p)$data[[1]] ; p + geom_area(data = subset(d, x > rand1), aes(x=x, y=y), fill="red") - user20650
1个回答

21

有一些问题展示了如何在使用ggplot2绘图时着色曲线下的区域,例如这里这里,但它们是在绘图前计算密度。

这是另一种方式,比需要的更复杂,它允许ggplot为您进行某些计算。

# Your data
set.seed(100)
amount_spent1 <- data.frame(amount_spent=rnorm(1000, 500, 150))

mean1 <- mean(amount_spent1$amount_spent)
rand1 <- runif(1,0,1000)

基础密度图

p <- ggplot(amount_spent1, aes(amount_spent)) +
          geom_density(fill="grey") +
          geom_vline(xintercept=mean1) 
你可以使用ggplot_build从绘图对象中提取用于着色的区域的xy位置。在x=rand1处使用线性插值来获取y值。
# subset region and plot
d <- ggplot_build(p)$data[[1]]

p <- p + geom_area(data = subset(d, x > rand1), aes(x=x, y=y), fill="red") +
          geom_segment(x=rand1, xend=rand1, 
                       y=0, yend=approx(x = d$x, y = d$y, xout = rand1)$y,
                       colour="blue", size=3)

这里输入图像描述


4
有十几个问题在问同样的事情,而这个答案是最清晰的。 - kmm

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接