PAYATHON 2026

如何在 ggplot2 ridge plot 中用不同颜色标记密度分布的尾部?

技术老齐

可以。将 geom_density_ridges() 换成 geom_density_ridges_gradient(),再把填充色映射到 after_stat(quantile),就能分别设置左尾、中间 95% 区域和右尾的颜色。模型拟合和 posterior draws 的整理代码都不用改。

为什么需要更换 geom?

geom_density_ridges() 通常为每条 ridge 使用一种填充色,而 geom_density_ridges_gradient() 允许填充色沿 x 轴变化,可以在同一条分布内按分位区间着色。ggridges 使用说明

设置 calc_ecdf = TRUE 后,密度统计层会生成 quantile 变量。配合 quantiles = c(0.025, 0.975),每个变量的分布会被划分为三个区间:

quantile对应区域
1左侧 2.5% 尾部
2中间 95% 区域
3右侧 2.5% 尾部

这些编号由统计层计算得出,需要用 after_stat() 引用,再通过 factor() 将它们作为离散类别映射到颜色。stat_density_ridges() 参数说明

替换绘图代码

生成 combined_iris 后,将原来的绘图部分替换为:

library(ggplot2)
library(ggridges)

ggplot(
  combined_iris,
  aes(
    x = value,
    y = variable,
    group = variable
  )
) +
  geom_density_ridges_gradient(
    aes(fill = after_stat(factor(quantile))),
    calc_ecdf = TRUE,
    quantiles = c(0.025, 0.975),
    quantile_lines = TRUE,
    scale = 0.9
  ) +
  geom_vline(
    xintercept = 0,
    linetype = "dashed"
  ) +
  scale_fill_manual(
    name = "后验分布区域",
    values = c(
      "1" = "#C6DBEF",
      "2" = "#2171B5",
      "3" = "#C6DBEF"
    ),
    breaks = c("1", "2", "3"),
    labels = c(
      "左尾 2.5%",
      "中间 95%",
      "右尾 2.5%"
    )
  ) +
  labs(
    x = "Posterior Estimates",
    y = "Variables",
    title = "Posterior Distributions (Iris Data)"
  ) +
  theme_minimal() +
  theme(legend.position = "bottom")

中间区域填充深蓝色,两侧尾部使用相同的浅蓝色。如果希望尾部颜色更深,交换相应色值即可。

用这段代码替换原来的 fill = variable 和 scale_fill_viridis_d() 后,颜色表示分位区间,各参数仍通过 y 轴标签区分。group = variable 指定按参数分组,分别计算密度和分位数。

使用时需要注意什么?

分位线可以关闭

如果只想用颜色区分区域,可以关闭示例中的分位线:

quantile_lines = FALSE

保留 calc_ecdf = TRUE,关闭分位线后仍需用它计算填色所需的 quantile 变量。

也可以使用 stat_density_ridges() 实现同样的效果,图层写法如下:

stat_density_ridges(
  aes(fill = after_stat(factor(quantile))),
  geom = "density_ridges_gradient",
  calc_ecdf = TRUE,
  quantiles = c(0.025, 0.975),
  quantile_lines = TRUE,
  scale = 0.9
)

用色值控制深浅

gradient geoms 对填充透明度有限制,因此不要直接沿用原代码中的 alpha = 0.5。直接设置浅色和深色色值更合适。gradient geom 文档

区分等尾区间与最高密度区间

c(0.025, 0.975) 标记的是 95% 等尾可信区间,两侧各留出约 2.5% 的后验概率。这个区间不一定与 95% 最高密度区间(HDI)重合,尤其是在偏态或多峰分布中。

分位边界根据后验样本计算,曲线来自核密度估计,因此图上深色区域的面积不能当作精确的数值积分结果。

原来的 coord_cartesian(xlim = c(-30, 40)) 还可能裁掉超出范围的尾部。示例省略了这一限制,确认分布范围后可以按需加回。

备注:内容仅供参考。