R语言ggplot2条形图如何自定义设置不同类别条形的填充颜色
问题根因
原代码直接将fill、color美学映射全局绑定到model字段,ggplot会为每个全局唯一的模型值分配固定颜色,导致无法实现「非B模型跨分类保持同色、仅B模型在不同分类下使用差异化配色」的规则,且提前定义的色板未正确接入比例尺。
修正代码
核心调整逻辑:
- 预处理阶段为每一行数据预计算对应的主题色:非B模型按模型名绑定固定色,B模型按所属分类分配差异化颜色
- 正负条形的边框色统一绑定预计算的主题色,负值条形固定填充白色
- 使用identity类比例尺直接读取预定义的颜色值,避免ggplot自动分配颜色
library(tidyverse) library(tidytext) df <- data.frame(model = c("A","B","C","D","B","C"), category = c("origin", "origin","origin","abroad","abroad","abroad"), pos = c(40,50,45,100,105,80), neg = c(-10,-5,-4,-16,-7,-2)) # 长宽转换+预计算每个条形对应的主题色 df <- df %>% pivot_longer(cols=c('pos','neg'), names_to = 'sign') %>% mutate( sign = factor(sign, levels = c("neg", "pos")), # 按规则分配颜色 bar_color = case_when( model == "A" ~ "chocolate", model == "C" ~ "yellow", model == "D" ~ "steelblue3", model == "B" & category == "origin" ~ "deeppink4", model == "B" & category == "abroad" ~ "steelblue3" ) ) ggplot() + # 绘制正值条形:填充、边框均用预定义色 geom_col(aes(value, tidytext::reorder_within(model, value, category), fill = bar_color, color = bar_color), data = df[df$sign == "pos", ], position = "stack") + # 绘制负值条形:填充固定为白色,边框和同组正值条形同色 geom_col(aes(value, tidytext::reorder_within(model, value, category), color = bar_color), data = df[df$sign == "neg", ], fill = "white", position = "stack") + # 直接使用预定义颜色值,不自动分配配色 scale_fill_identity() + scale_color_identity() + tidytext::scale_y_reordered() + facet_grid(category ~ ., switch = "y",scales = "free_y") + theme(axis.text.x = element_text(angle = 90), strip.background = element_rect(fill = "white"), strip.placement = "outside", strip.text.y.left = element_text(angle = 0), panel.spacing = unit(0, "lines")) + theme(legend.position="none") + labs( title = "BarPlot", subtitle = "changes", y = " ")
实现效果
- A、C、D模型跨分类保持统一配色:A为巧克力色、C为黄色、D为钢蓝色
- B模型按分类差异化配色:origin类下为深粉色、abroad类下为钢蓝色
- 所有负值条形填充为白色,边框颜色与对应组正值条形完全一致
内容的提问来源于stack exchange,提问作者user18937485
相关产品推荐
相关产品推荐

