ggplot2中密度曲线下的阴影区域

Posted

技术标签:

【中文标题】ggplot2中密度曲线下的阴影区域【英文标题】:Shaded area under density curve in ggplot2 【发布时间】:2018-06-21 02:56:50 【问题描述】:

我已经绘制了一个分布,我想对该区域进行着色>95%。 但是,当我尝试使用此处记录的不同技术时:ggplot2 shade area under density curve by group 它不起作用,因为我的数据集长度不同。

AGG[,1]=seq(1:1000)
AGG[,2]=rnorm(1000,mean=150,sd=10)
Z<-data.frame(AGG) 
library(ggplot2)
ggplot(Z,aes(x=Z[,2]))+stat_density(geom="line",colour="lightblue",size=1.1)+xlim(0,350)+ylim(0,0.05)+geom_vline(xintercept=quantile(Z[,2],prob=0.95),colour="red")+geom_text(aes(x=quantile(Z[,2],prob=0.95)),label="VaR 95%",y=0.0225, colour="red")
#I want to add a shaded area right of the VaR in this chart

【问题讨论】:

是否有必要使用rnorm 从分布中抽取随机数,还是使用dnorm 绘制经验函数就足够了? 实际上我不能使用 dnorm 或类似的东西,因为我的分布不遵循通常的规律,我使用蒙特卡罗模拟来估计它。因此,假设 AGG[,2] 是任何给定的随机数,我想为其绘制密度并在第 95 个百分位以上的区域着色 感谢你们两位的有用回答。太糟糕了,在 GGplot 上对区域进行着色比在 R 中使用通常的绘图函数更复杂。 这能回答你的问题吗? Shading a kernel density plot between two points. 【参考方案1】:

这是使用函数WVPlots::ShadedDensity 的解决方案。我将使用这个函数,因为它的参数是不言自明的,因此可以很容易地创建绘图。不利的一面是,定制有点棘手。但是,一旦您仔细研究了 ggplot 对象,您就会发现它并没有那么神秘。

library(WVPlots)

# create the data
set.seed(1)
V1 = seq(1:1000)
V2 = rnorm(1000, mean = 150, sd = 10)
Z <- data.frame(V1, V2)

现在你可以创建你的情节了。

threshold <- quantile(Z[, 2], prob = 0.95)[[1]]
p <- WVPlots::ShadedDensity(frame = Z, 
                            xvar = "V2",
                            threshold = threshold,
                            title = "Your title",
                            tail = "right")
p

但由于您希望线条的颜色为浅蓝色等,您需要操作对象p。在这方面,另请参阅this 和this 问题。

对象p 包含四个层:geom_linegeom_ribbongeom_vlinegeom_text。你可以在这里找到它们:p$layers

现在您需要更改它们的美学映射。对于geom_line,只有一个colour

p$layers[[1]]$aes_params
$colour
[1] "darkgray"

如果您现在想将线条颜色更改为浅蓝色,只需像这样覆盖现有颜色

p$layers[[1]]$aes_params$colour <- "lightblue"

一旦你想出了如何为一个 layer 做到这一点,剩下的就很容易了。

p$layers[[2]]$aes_params$fill <- "grey"     #geom_ribbon
p$layers[[3]]$aes_params$colour <- "red"    #geom_vline
p$layers[[4]]$aes_params$label <- "VaR 95%" #geom_text

p

现在的情节是这样的

【讨论】:

非常优雅且易于实施的解决方案!【参考方案2】:

在这种情况下,ggplot 的辅助函数和内置摘要最终可能会比有用更麻烦。在您的情况下,最好直接计算汇总统计数据,然后绘制它们。在下面的示例中,我使用基础 stats 库中的 densityquantile 来计算将要绘制的内容。将其直接提供给 ggplot 比尝试操作 ggplot 的摘要函数要简单得多。这样,使用geom_ribbon 和 ggplot 的预期美学系统来完成着色;无需深入挖掘绘图对象。

rm(list = ls())
library(magrittr)
library(ggplot2)

y <- rnorm(1000, 150, 10)

cutoff <- quantile(y, probs = 0.95)

hist.y <- density(y, from = 100, to = 200) %$% 
  data.frame(x = x, y = y) %>% 
  mutate(area = x >= cutoff)

the.plot <- ggplot(data = hist.y, aes(x = x, ymin = 0, ymax = y, fill = area)) +
  geom_ribbon() +
  geom_line(aes(y = y)) +
  geom_vline(xintercept = cutoff, color = 'red') +
  annotate(geom = 'text', x = cutoff, y = 0.025, color = 'red', label = 'VaR 95%', hjust = -0.1)
print(the.plot)

【讨论】:

以上是关于ggplot2中密度曲线下的阴影区域的主要内容,如果未能解决你的问题,请参考以下文章

ggplot2:如何在回归线上曲线小高斯密度?

R(ggplot2)中密度图下的梯度着色

使用 ggplot2 沿平滑曲线绘制直方图或密度

R语言ggplot2可视化:ggplot2可视化密度图(显示数据密集区域)ggplot2可视化密度图(对数坐标):log10比例的收入密度图突出了在常规密度图中很难看到的收入分布细节

R语言ggplot2可视化:使用R原生plot函数为指定曲线下面的区域着色ggplot2可视化在曲线的特定下方添加分割线ggplot2为指定曲线下面的区域着色

R语言ggplot2可视化:ggplot2可视化散点图并使用geom_mark_ellipse函数在数据簇或数据分组的数据点周围添加椭圆(ellipse)进行注释(对椭圆包围的区域进行着色为阴影区域)