使用ggplot绘制单栏堆叠柱状图,实现红绿占比段置于蓝色总柱前方的效果
分层堆叠SSE柱状图实现方案
原有代码的问题
当前代码仅将每个模型的总SSE值映射为单根纯色柱,既没有拆分分量的分层结构,也没有实现“蓝柱为视觉底层、红绿段叠加在上”的效果,需要按以下逻辑调整。
核心实现规则
- ggplot的图层绘制顺序为先写在下、后写在上,最先定义的几何对象会处于视觉最底层,后续叠加的对象会覆盖在其上方,刚好匹配“蓝柱垫底、红绿段在前”的视觉要求
- 两个拆分分量的累加值必须小于等于对应模型的总SSE值,保证红绿段的总高度不会超出蓝柱的高度范围
分步实现代码
- 调整数据结构:在原有总SSE数据基础上,补充两个拆分分量的实际计算值,将分量数据转换为长格式适配堆叠逻辑
library(tibble) library(ggplot2) library(tidyr) # 基础总SSE数据 sse_total <- c(3243.784, 2527.5, 716.3) model <- c('sst', 'ssm', 'ssr') # 替换为实际业务对应的两个拆分分量值 sse_comp1 <- c(1200, 900, 200) # 对应绿色分量段 sse_comp2 <- c(800, 600, 250) # 对应红色分量段 bar <- tibble( model = model, sse_total = sse_total, sse_comp1 = sse_comp1, sse_comp2 = sse_comp2 ) # 将分量数据转换为长格式,适配堆叠绘制逻辑 bar_comp <- bar %>% pivot_longer( cols = c(sse_comp1, sse_comp2), names_to = "comp_type", values_to = "comp_value" ) - 按正确图层顺序绘图
ggplot() + # 第一层:绘制最底层的全高总SSE蓝色柱 geom_col( data = bar, aes(x = model, y = sse_total), fill = "#2c7fb8", width = 0.6 ) + # 第二层:在蓝柱上方叠加红绿分量堆叠段 geom_col( data = bar_comp, aes(x = model, y = comp_value, fill = comp_type), width = 0.6 ) + # 手动指定分量对应颜色,匹配设计要求 scale_fill_manual( values = c("sse_comp1" = "#31a354", "sse_comp2" = "#de2d26"), labels = c("分量1", "分量2") ) + theme_bw() + labs(x = "模型类别", y = "平方误差(SSE)")
注意事项
- 所有几何对象的
width参数必须保持一致,避免不同图层的柱体宽度不匹配出现错位 - 图层顺序不可调换:若将红绿分量段的代码放在蓝柱之前,蓝柱会直接覆盖分量段,无法看到拆分效果
- 绘制前校验分量数值:每个模型的两个分量累加值必须≤对应总SSE值,避免出现分量段超出蓝柱高度的视觉偏差
内容的提问来源于stack exchange,提问作者Cmagelssen
相关产品推荐
相关产品推荐

