如何在 ggplot 中遮蔽部分密度曲线(没有 y 轴数据)
How to shade part of a density curve in ggplot (with no y axis data)
我正在尝试使用一组介于 1000 之间的随机数在 R 中创建密度曲线,并对小于或等于某个值的部分进行阴影处理。有很多涉及 geom_area
或 geom_ribbon
的解决方案,但它们都需要 yval
,而我没有(它只是一个包含 1000 个数字的向量)。关于如何做到这一点有什么想法吗?
其他两个相关问题:
- 是否可以对累积密度函数做同样的事情(我目前正在使用
stat_ecdf
生成一个),或者完全遮蔽它?
- 有什么方法可以编辑
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))
有几个问题表明了这一点……here and here,但它们在绘图之前计算了密度。
这是另一种方法,我敢肯定比要求的更复杂,它允许 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
从绘图对象中提取阴影区域的 x
和 y
位置。使用线性插值在 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)
我正在尝试使用一组介于 1000 之间的随机数在 R 中创建密度曲线,并对小于或等于某个值的部分进行阴影处理。有很多涉及 geom_area
或 geom_ribbon
的解决方案,但它们都需要 yval
,而我没有(它只是一个包含 1000 个数字的向量)。关于如何做到这一点有什么想法吗?
其他两个相关问题:
- 是否可以对累积密度函数做同样的事情(我目前正在使用
stat_ecdf
生成一个),或者完全遮蔽它? - 有什么方法可以编辑
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))
有几个问题表明了这一点……here and here,但它们在绘图之前计算了密度。
这是另一种方法,我敢肯定比要求的更复杂,它允许 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
从绘图对象中提取阴影区域的 x
和 y
位置。使用线性插值在 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)