ggridges中组内而非组间的缩放问题求助
解决ggridges组内缩放、组间高度统一的分布可视化问题
当使用ggridges可视化多组内的群体分布时,若组间样本量差异显著(如示例中组c样本量是a、b的10倍),会遇到两个痛点:
- 默认绘图用密度归一化,导致组内不同群体视觉上规模一致,无法体现实际样本量差异;
- 直接映射
height=..count..会让大样本组的曲线完全覆盖小样本组,无法辨识小组内的分布。
需求是:组内按样本量比例缩放,保留群体间的规模差异;组间高度统一,无需体现组间样本量差距,仅关注每组内的分布对比。
解决方案
核心思路是手动计算密度并按组归一化高度,具体步骤如下:
1. 生成示例数据并预处理
library(dplyr) library(ggplot2) library(ggridges) # 生成用户提供的示例数据 sa_dog = data.frame(group = "a", value = rnorm(n = 50, mean = 0, sd = 1), species = "dog") sb_dog = data.frame(group = "b", value = rnorm(n = 50, mean = 0, sd = 1), species = "dog") sc_dog = data.frame(group = "c", value = rnorm(n = 500, mean = 0, sd = 1), species = "dog") sa_cat = data.frame(group = "a", value = rnorm(n = 10, mean = 1.5, sd = 0.5), species = "cat") sb_cat = data.frame(group = "b", value = rnorm(n = 10, mean = 1.5, sd = 0.5), species = "cat") sc_cat = data.frame(group = "c", value = rnorm(n = 100, mean = 1.5, sd = 0.5), species = "cat") df <- bind_rows(sa_dog, sb_dog, sc_dog, sa_cat, sb_cat, sc_cat) # 计算归一化后的密度高度 df_scaled <- df %>% group_by(group, species) %>% # 提取密度曲线的x轴数值和原始高度(count) reframe( dens = density(value), value = dens$x, count = dens$y ) %>% select(-dens) %>% # 按组归一化高度:每组内最大高度设为1,其他按比例缩放 group_by(group) %>% mutate( max_group_count = max(count), scaled_height = count / max_group_count ) %>% ungroup()
2. 使用归一化高度绘图
ggplot(df_scaled, aes(x = value, y = group, fill = species, height = scaled_height)) + geom_density_ridges(alpha = 0.5, scale = 0.98, stat = "identity") + theme_minimal() + labs( x = "数值", y = "组别", fill = "物种", title = "组内按样本量缩放,组间高度统一的分布对比" )
原理说明
- 手动计算密度:通过
density()函数获取每个组-物种组合的密度曲线数据,得到原始的曲线高度(count)和x轴数值; - 组内归一化:对每个组别,将所有物种的
count除以该组内的最大count,确保每组内样本量最大的群体曲线高度统一为1,其他群体按实际样本量比例缩放,保留组内规模差异; - 组间高度统一:所有组的高度基准一致,避免大样本组压制小样本组,能清晰对比每组内两个物种的分布形态与相对规模。
内容的提问来源于stack exchange,提问作者Jaken
相关产品推荐
相关产品推荐

