You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在ggplot2脊线图中为密度分布尾部设置不同颜色?

解决方案:给ggridges脊线图的后验分布尾部上色

要实现95%区间外的尾部用不同颜色标记,核心是先为每个观测值划分区间类别,再通过fill映射这个类别来区分颜色。以下是修改后的完整代码:

# load libraries
library(tidyverse)
library(ggridges)
library(brms)
library(viridis)

# load iris data set
data(iris)
str(iris)
table(iris$Species)

# drop the level "setosa" because we want to compare versicolor and virginica
iris <- iris[iris$Species != "setosa", ]
# drop the level "setosa" in the variable "Species" because we only have two groups now (versicolor vs virginica)
iris$Species <- droplevels(iris$Species)

# fit a simple logistic regression model using brms
logistic_iris <- brm(
  formula = Species ~ Sepal.Length + Sepal.Width + Petal.Length + Petal.Width,
  data = iris,
  family = bernoulli(link = "logit"),
  chains = 4,
  iter = 2000,
  warmup = 500,
  seed = 6845112
)

summary(logistic_iris)
draws_logistic_iris <- as_draws_df(logistic_iris)

variables_iris <- c("b_Sepal.Length", "b_Sepal.Width", "b_Petal.Length", "b_Petal.Width")

# Initialize an empty data frame
combined_iris <- data.frame()

# Loop through variables to extract posterior draws and combine into a data frame
for (var in variables_iris) {
  
  variable_name <- var
  
  draws <- posterior::as_draws(logistic_iris, variable = variable_name)
  
  draws_df <- posterior::as_draws_df(draws)
  
  # Prepare the draws
  combined_temp <- data.frame(
    value = draws_df[[variable_name]],
    variable = var
  )
  
  # Combine with the main data frame
  combined_iris <- rbind(combined_iris, combined_temp)
}

# -------------------------- 新增:计算分位数并标记区间类别 --------------------------
# 按变量分组计算95%CI的分位数
quantile_df <- combined_iris %>%
  group_by(variable) %>%
  summarize(
    q025 = quantile(value, 0.025),
    q975 = quantile(value, 0.975)
  )

# 为每个观测值标记区间:左尾(<2.5%)、中间(2.5%-97.5%)、右尾(>97.5%)
combined_iris <- combined_iris %>%
  left_join(quantile_df, by = "variable") %>%
  mutate(
    interval = case_when(
      value < q025 ~ "左尾部",
      value > q975 ~ "右尾部",
      TRUE ~ "95%区间"
    ) %>% factor(levels = c("左尾部", "95%区间", "右尾部")) # 指定顺序,方便颜色映射
  )

# -------------------------- 修改绘图代码 --------------------------
ggplot(combined_iris, aes(x = value, y = variable, fill = interval)) +
  # 使用stat_density_ridges,搭配渐变填充geom实现区间上色
  stat_density_ridges(
    geom = "density_ridges_gradient",
    scale = 1,
    alpha = 0.8,
    rel_min_height = 0.01 # 过滤极低密度的线条
  ) +
  geom_vline(aes(xintercept = 0), linetype = "dashed") +
  labs(x = "Posterior Estimates", y = "Variables", title = "Posterior Distributions (Iris Data)") +
  coord_cartesian(xlim = c(-30, 40)) +
  # 自定义区间颜色,可根据需求调整
  scale_fill_viridis_d(
    name = "区间",
    breaks = c("95%区间", "左尾部", "右尾部"),
    values = c("95%区间" = "#440154FF", "左尾部" = "#21908CFF", "右尾部" = "#FDE725FF")
  ) +
  theme_minimal() +
  theme(legend.position = "bottom")

关键修改说明:

  • 数据预处理:按变量分组计算95%置信区间的分位数,用case_when为每个观测值标记所属区间类别(左尾、中间95%、右尾)。
  • 绘图核心设置:使用stat_density_ridges并指定geom = "density_ridges_gradient",这是实现不同区间颜色填充的关键,它支持按分组变量区分填充色。
  • 颜色自定义:通过scale_fill_viridis_d设置各区间的颜色,你可以替换成同色系深浅变化(比如中间浅、尾部深)或其他偏好配色。

内容的提问来源于stack exchange,提问作者Linus

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.01 21:44:51