如何在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
相关产品推荐
相关产品推荐

