如何为ggplot2生成的密度图添加基于上下限的带状填充(置信区间样式)
如何为ggplot2生成的密度图添加基于上下限的带状填充(置信区间样式)
我明白你想要的效果:给每个分组的密度线,用对应颜色的半透明填充带把Lower到Upper的x轴区间包裹起来,类似置信区间的视觉效果。咱们一步步来实现这个需求:
第一步:整理你的数据
你提供的对象是一个ggplot对象,实际数据集存在它的data字段里,先把数据提取出来并清理缺失值:
library(ggplot2) library(dplyr) library(tidyr) # 从你提供的ggplot对象中提取原始数据集 pdf_data <- pdf1$data # 清理包含缺失值的行(保证后续计算正常) pdf_clean <- pdf_data %>% drop_na(Mean, Lower, Upper)
第二步:为每个分组生成密度曲线数据
我们需要为每个Group单独计算密度曲线的x值和对应密度值,同时绑定该分组的上下限区间:
# 为每个分组生成密度数据,并关联对应的上下限 density_data <- pdf_clean %>% group_by(Group) %>% group_modify(function(data, group) { # 计算当前分组的密度曲线,adjust参数可调整平滑程度(数值越大越平滑) dens <- density(data$Mean, adjust = 1.5) # 生成包含x轴值、密度值、分组上下限的数据框 tibble( x = dens$x, density = dens$y, # 这里取分组内上下限的均值作为该组的整体区间,你也可以根据需求改成min(Lower)/max(Upper) Lower = mean(data$Lower, na.rm = TRUE), Upper = mean(data$Upper, na.rm = TRUE) ) }) %>% ungroup()
第三步:绘制带填充带的密度图
用geom_ribbon绘制上下限区间内的填充带,再叠加原来的密度线:
ggplot() + # 添加半透明填充带:仅填充x在Lower到Upper之间的区域 geom_ribbon( data = density_data %>% filter(x >= Lower, x <= Upper), aes(x = x, ymin = 0, ymax = density, fill = Group), alpha = 0.2 # 调整透明度,避免遮挡线条和其他分组 ) + # 添加密度线,保持你原来的颜色和线型设置 geom_line( data = density_data, aes(x = x, y = density, colour = Group, linetype = Group), linewidth = 1 ) + # 标签与标题设置 xlab("March maximum temperature") + ylab("Probability density function") + ggtitle("Probability density functions (PDF) in comparison with observations") + # 手动设置颜色、线型、填充色,保证视觉一致性 scale_linetype_manual( values = c('solid', 'solid','solid','dotted'), labels = c("Observation", "Historical", "Future", "Downscaled") ) + scale_colour_manual( values = c("black", "green", "blue", "red"), labels = c("Observation", "Historical", "Future", "Downscaled") ) + scale_fill_manual( values = c("black", "green", "blue", "red"), labels = c("Observation", "Historical", "Future", "Downscaled") ) + theme_minimal()
补充说明
- 如果你的分组内
Lower和Upper不是统一区间(比如每个站点上下限都不同),可以把mean(data$Lower)改成min(data$Lower),mean(data$Upper)改成max(data$Upper),这样填充的是整个分组的最小到最大区间范围。 adjust参数可以根据数据分布调整密度曲线的平滑度,你可以尝试不同数值找到最合适的效果。alpha参数控制填充带的透明度,数值越小越透明,能更好地保留线条的可读性。
备注:内容来源于stack exchange,提问作者sdorji
相关产品推荐
相关产品推荐

