R ggplot2如何绘制固定配色、按占比排序的单堆叠条形图
问题原因
arrange() 调整数据框行顺序后绘图不生效,是因为ggplot2绘制堆叠条形图时,分段的堆叠顺序完全由fill映射变量的因子水平顺序决定,和数据行的排列顺序无关。你之前手动将reason_factor的因子水平固定为写死的顺序,因此无论怎么重排数据集,堆叠顺序都不会改变。
解决方案
要同时满足「按占比动态排序堆叠分段」+「固定各原因对应配色(Reason 1始终为黄色)」两个要求,只需要做两处核心调整:
- 按占比排序数据集后,动态将
reason转为因子,因子水平与排序后的reason列顺序一致,用因子水平控制堆叠顺序 - 给
scale_fill_manual传入带名称的颜色映射向量,让颜色和原因名称直接绑定,而非按因子位置匹配,这样无论因子顺序怎么调整,配色都不会错位。
修正后的可运行代码:
library(dplyr) library(ggplot2) library(scales) # 测试数据集 test_dataset <- tibble(reason = c("Reason 1", "Reason 2", "Reason 3", "Reason 4", "Reason 5"), percentage = c(.10, .35, .25, .15, .15), filler_variable = "filler_variable") # 定义带名称的固定配色:直接绑定每个原因对应的颜色,Reason 1固定为黄色 reason_colors <- c( "Reason 1" = "yellow", "Reason 2" = "red", "Reason 3" = "blue", "Reason 4" = "green", "Reason 5" = "orange" ) test_dataset <- test_dataset %>% # 按占比降序排列,占比持平的条目顺序不做强制要求 arrange(desc(percentage)) %>% # 动态设置因子水平,顺序和排序后的原因一致,控制堆叠顺序 mutate(reason_factor = factor(reason, levels = reason)) # 绘制图形 test_dataset %>% ggplot(aes(x = filler_variable, y = percentage, fill = reason_factor)) + # 原始数据百分比求和为1,直接用position_stack即可,无需position_fill重复归一化 geom_col(position = position_stack(), width = 0.4) + coord_flip() + scale_y_continuous(labels = percent_format(accuracy = 1), limits = c(0, 1)) + # 传入命名配色向量,保持原有图例排版 scale_fill_manual(values = reason_colors, guide = guide_legend(reverse = TRUE, nrow=2, byrow=TRUE))
补充说明
- 如果需要调整堆叠的上下顺序(比如让占比最高的分段最贴近坐标轴),只需要把
arrange(desc(percentage))改为arrange(percentage)升序排列即可,配色不会发生任何错位。 - 后续如果新增/修改差评原因,只需要在
reason_colors里新增对应的名称和颜色映射即可,不需要调整其他绘图逻辑。
内容的提问来源于stack exchange,提问作者J.Sabree
相关产品推荐
相关产品推荐

