You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何独立于fill变量设置ggbarplot条形颜色:按type或交替同色

问题描述

数据集

vartypeyearpercperc_SE
migGesamt20160.350.02
migGesamt20210.420.03
migKlasse20160.060.00
migKlasse20210.170.00
cbookslGesamt20160.670.01
cbookslGesamt20210.680.02
cbookslKlasse20160.790.00
cbookslKlasse20210.650.00

当前代码

cbbPalette <- c("#00a0a0", "#a3dee1")

data$var <- factor(data$var, levels = c("mig","cbooksl"))
data$type <- factor(data$type, levels = c("Klasse", "Gesamt"))

ggplot(data, aes(x=type, width = 0.8, y=perc, fill=factor(year, c("2021", "2016")))) + 
  geom_bar(position=position_dodge(width=0.9), stat="identity", color = "black") + 
  geom_errorbar(data=subset(data, perc_SE > 0), aes(ymin=perc - 2*perc_SE, ymax=perc + 2*perc_SE), width=.3,
                position=position_dodge(.9)) +
  geom_text(aes(label =paste(as.character(round(perc * 100)), "%"), y = 0.03), colour = "black",
            position=position_dodge(width=0.8), fontface="bold", size=3.25) + 
  theme_bw() + 
  geom_text(aes(y=-0.039, label=year, fontface="bold"), position=position_dodge(width=1), color="black", size=3) + 
  theme(legend.position = "none", title = element_blank(),
        axis.title.y=element_blank(), axis.text.y = element_text(angle = 90, vjust = -27, hjust=0.5),
        axis.ticks.y=element_blank(), axis.line.x = element_line(colour = "black", 
        size = 0.1, linetype = "solid"),   
        strip.text.y = element_text(angle=0), panel.border = element_blank(), strip.background = element_blank(),
        panel.grid.major.y = element_blank(), panel.spacing = unit(0, "lines")) +
  coord_flip() +
  scale_fill_manual(values=cbbPalette)  +
  facet_grid(var~., switch = "y", margins = F) + 
  scale_y_continuous(breaks=c(0,0.2,0.4,0.6,0.8,1), minor_breaks = c(0,0.2,0.4,0.6,0.8,1),
                     sec.axis = sec_axis(~. *1, breaks = c(0,0.2,0.4,0.6,0.8,1),
          labels = c("0%","20%","40%","60%","80%","100%")), position = "right",
        labels=c("0%","20%", "40%", "60%", "80%", "100%"), limits = c(-0.039,1))

需求

希望调整条形颜色,实现以下两种效果之一:

  1. 条形颜色依赖type变量的值,且不更改其他设置;
  2. 手动设置颜色,让连续两个条形交替使用相同颜色。

尝试过cbbPalette <- c("#00a0a0", "#00a0a0", "#a3dee1", "#a3dee1")但所有条形都变成#00a0a0;尝试将type设为fill参数却破坏了整个图表,寻求解决方法。


解决方案

效果1:按type变量设置条形颜色

核心是将fill映射从year改为type,同时保证所有图层的 dodge 逻辑一致,避免布局混乱:

cbbPalette <- c("#00a0a0", "#a3dee1") # 对应Klasse、Gesamt的颜色

data$var <- factor(data$var, levels = c("mig","cbooksl"))
data$type <- factor(data$type, levels = c("Klasse", "Gesamt"))

ggplot(data, aes(x=type, width = 0.8, y=perc, fill=type)) + 
  geom_bar(position=position_dodge(width=0.9), stat="identity", color = "black") + 
  geom_errorbar(data=subset(data, perc_SE > 0), aes(ymin=perc - 2*perc_SE, ymax=perc + 2*perc_SE), width=.3,
                position=position_dodge(.9)) +
  geom_text(aes(label =paste(as.character(round(perc * 100)), "%"), y = 0.03), colour = "black",
            position=position_dodge(width=0.8), fontface="bold", size=3.25) + 
  theme_bw() + 
  # 为year文本单独指定group=year,保证按年份dodge排列
  geom_text(aes(y=-0.039, label=year, fontface="bold", group=year), position=position_dodge(width=1), color="black", size=3) + 
  theme(legend.position = "none", title = element_blank(),
        axis.title.y=element_blank(), axis.text.y = element_text(angle = 90, vjust = -27, hjust=0.5),
        axis.ticks.y=element_blank(), axis.line.x = element_line(colour = "black", 
        size = 0.1, linetype = "solid"),   
        strip.text.y = element_text(angle=0), panel.border = element_blank(), strip.background = element_blank(),
        panel.grid.major.y = element_blank(), panel.spacing = unit(0, "lines")) +
  coord_flip() +
  scale_fill_manual(values=cbbPalette)  +
  facet_grid(var~., switch = "y", margins = F) + 
  scale_y_continuous(breaks=c(0,0.2,0.4,0.6,0.8,1), minor_breaks = c(0,0.2,0.4,0.6,0.8,1),
                     sec.axis = sec_axis(~. *1, breaks = c(0,0.2,0.4,0.6,0.8,1),
          labels = c("0%","20%","40%","60%","80%","100%")), position = "right",
        labels=c("0%","20%", "40%", "60%", "80%", "100%"), limits = c(-0.039,1))

效果2:连续两个条形交替使用相同颜色

创建新的分组变量,让同type下的两年条形共享同一颜色,再映射到fill:

cbbPalette <- c("#00a0a0", "#a3dee1") # 对应两组交替颜色

data$var <- factor(data$var, levels = c("mig","cbooksl"))
data$type <- factor(data$type, levels = c("Klasse", "Gesamt"))
# 按type分组,每组内的两个年份归为同一颜色组
data$color_group <- factor(data$type)

ggplot(data, aes(x=type, width = 0.8, y=perc, fill=color_group)) + 
  geom_bar(position=position_dodge(width=0.9), stat="identity", color = "black") + 
  geom_errorbar(data=subset(data, perc_SE > 0), aes(ymin=perc - 2*perc_SE, ymax=perc + 2*perc_SE), width=.3,
                position=position_dodge(.9)) +
  geom_text(aes(label =paste(as.character(round(perc * 100)), "%"), y = 0.03), colour = "black",
            position=position_dodge(width=0.8), fontface="bold", size=3.25) + 
  theme_bw() + 
  geom_text(aes(y=-0.039, label=year, fontface="bold", group=year), position=position_dodge(width=1), color="black", size=3) + 
  theme(legend.position = "none", title = element_blank(),
        axis.title.y=element_blank(), axis.text.y = element_text(angle = 90, vjust = -27, hjust=0.5),
        axis.ticks.y=element_blank(), axis.line.x = element_line(colour = "black", 
        size = 0.1, linetype = "solid"),   
        strip.text.y = element_text(angle=0), panel.border = element_blank(), strip.background = element_blank(),
        panel.grid.major.y = element_blank(), panel.spacing = unit(0, "lines")) +
  coord_flip() +
  scale_fill_manual(values=cbbPalette)  +
  facet_grid(var~., switch = "y", margins = F) + 
  scale_y_continuous(breaks=c(0,0.2,0.4,0.6,0.8,1), minor_breaks = c(0,0.2,0.4,0.6,0.8,1),
                     sec.axis = sec_axis(~. *1, breaks = c(0,0.2,0.4,0.6,0.8,1),
          labels = c("0%","20%","40%","60%","80%","100%")), position = "right",
        labels=c("0%","20%", "40%", "60%", "80%", "100%"), limits = c(-0.039,1))

如果需要纯按顺序每两个条形一组(不依赖type),可以用gl()生成分组:

data$color_group <- gl(nrow(data)/2, 2) # 每2行分为一组

内容的提问来源于stack exchange,提问作者Joshua_ABC

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.22 16:07:12