ggplot2:统一前9年条形颜色并简化图例为两项
解决方案
核心问题在于你直接用原始的cohort变量映射填充色,前9年是9个不同类别,导致scale_fill_manual无法统一它们的颜色。解决思路是先对年份进行分组,将前9年归为同一类别,再基于这个分组变量设置填充色,同时保留原始年份的分组来确保每个年份的条形单独显示。
步骤1:预处理数据,新增分组变量
在数据中添加一个新变量fill_group,把前9年统一标记为"Year 1 - 9",第10年标记为"Year 10":
library(dplyr) library(ggplot2) library(stringr) # 原数据生成代码 tit <- "Title" subtit <- "Subtitle" lab <- c("lab1", "lab2", "lab3", "lab4") n_label <- length(lab) cohort <- c(rep("year01", n_label), rep("year02", n_label), rep("year03", n_label), rep("year04", n_label), rep("year05", n_label), rep("year06", n_label), rep("year07", n_label), rep("year08", n_label), rep("year09", n_label), rep("year10", n_label)) data_rel <- runif(40, min = 0, max = .5) df_data <- data.frame(lab, cohort, data_rel) # 新增填充分组变量 df_data <- df_data %>% mutate(fill_group = ifelse(cohort == "year10", "Year 10", "Year 1 - 9"))
步骤2:修改绘图代码
关键修改点:
- 将
fill映射改为新的fill_group变量 - 添加
group = cohort,确保每个年份的条形单独显示(避免前9年被合并) - 简化
scale_fill_manual,直接对应新的分组标签和颜色
完整绘图代码:
df_data %>% ggplot(aes( x = factor(lab, levels = c("lab1", "lab2", "lab3", "lab4")), y = data_rel, fill = fill_group, group = cohort # 强制按原始年份分组,保证10个条形都显示 )) + geom_bar(stat = "identity", position = position_dodge()) + scale_y_continuous(labels = scales::percent, limits = c(0, 1)) + theme_classic() + theme( legend.position = "bottom", plot.title = element_text(hjust = 0.5, size = 14, face = "bold"), plot.subtitle = element_text(hjust = 0.5), plot.caption = element_text(hjust = 0.5) ) + geom_text( data = subset(df_data, cohort == "year10"), aes( x = lab, y = data_rel, label = paste0(sprintf("%.1f", data_rel * 100), "%") ), vjust = -1, hjust = -1.5, size = 3 ) + scale_fill_manual( values = c("Year 1 - 9" = "#7F7F7F", "Year 10" = "#389DC3") ) + labs( subtitle = subtit, title = str_wrap(tit, 45), x = "", y = "", fill = "" )
修改说明
- 统一前9年颜色:通过
fill_group把前9年归为同一类别,填充色映射时直接给这个类别设置统一颜色,避免了9个年份分别设置的麻烦。 - 保留10个独立条形:添加
group = cohort告诉ggplot,即使填充色相同,也要按原始年份分组显示每个条形,不会合并前9年的条形。 - 自动生成正确图例:
fill_group只有两个类别,图例自然只会显示"Year 1 - 9"和"Year 10"两个条目,无需额外过滤。
内容的提问来源于stack exchange,提问作者Dierforth
相关产品推荐
相关产品推荐

