如何独立于fill变量设置ggbarplot条形颜色:按type或交替同色
问题描述
数据集
| var | type | year | perc | perc_SE |
|---|---|---|---|---|
| mig | Gesamt | 2016 | 0.35 | 0.02 |
| mig | Gesamt | 2021 | 0.42 | 0.03 |
| mig | Klasse | 2016 | 0.06 | 0.00 |
| mig | Klasse | 2021 | 0.17 | 0.00 |
| cbooksl | Gesamt | 2016 | 0.67 | 0.01 |
| cbooksl | Gesamt | 2021 | 0.68 | 0.02 |
| cbooksl | Klasse | 2016 | 0.79 | 0.00 |
| cbooksl | Klasse | 2021 | 0.65 | 0.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))
需求
希望调整条形颜色,实现以下两种效果之一:
- 条形颜色依赖
type变量的值,且不更改其他设置; - 手动设置颜色,让连续两个条形交替使用相同颜色。
尝试过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
相关产品推荐
相关产品推荐

