在带自由刻度分面的ggplot中固定y轴中点添加geom_pointrange
解决分面密度图中固定y轴中点添加统计区间的问题
要实现每个分面里geom_pointrange固定在y轴中点,核心是先获取每个分面密度曲线的y轴最大值,再计算对应中点值,具体实现如下:
步骤1:计算每个分面的密度峰值与中点值
先让ggplot生成密度计算数据,从中提取每个分组的y轴最大值,再推导中点:
library(ggplot2) library(dplyr) # 构造基础数据 data <- iris %>% mutate(grouping1 = rep(1:3, length.out = nrow(iris)), variable = Sepal.Length) # 提取ggplot内部计算的密度数据,获取每个分面的y轴最大值 density_stats <- ggplot_build(ggplot(data) + geom_density(aes(x = variable)) + facet_wrap(~grouping1, scales = "free")) %>% pluck("data", 1) %>% group_by(PANEL) %>% mutate(grouping1 = as.integer(levels(data$grouping1)[PANEL])) %>% summarise(max_y = max(y)) # 合并统计值与中点值 data_summ <- data %>% group_by(grouping1) %>% summarise(variable = mean(Sepal.Length), lower = quantile(Sepal.Length, 0.025), upper = quantile(Sepal.Length, 0.975)) %>% left_join(density_stats, by = "grouping1") %>% mutate(mid_y = max_y / 2)
步骤2:绘制带固定中点区间的分面密度图
用计算好的mid_y作为geom_pointrange的y轴定位值:
ggplot(data) + geom_density(aes(x = variable, fill = grouping1), alpha = 0.7) + geom_pointrange(data = data_summ, aes(x = variable, xmin = lower, xmax = upper, y = mid_y), color = "black", size = 0.8) + facet_wrap(~ grouping1, scales = "free") + theme_minimal()
关键说明
- 通过
ggplot_build()提取ggplot内部的密度计算结果,能精准获取自由刻度下每个分面的y轴最大值,避免手动估算的误差。 - 直接用最大值除以2得到中点,确保每个分面的统计区间都处于y轴垂直居中位置。
内容的提问来源于stack exchange,提问作者mk123
相关产品推荐
相关产品推荐

