ggplot2中为分面geom_bar图形应用统一调色板的实现方法
问题描述
我正尝试为带分面设置的geom_bar条形图应用调色板,现有实现代码如下:
est21 <- structure(list(Zona = c("Urbana", "Urbana", "Urbana", "Rural", "Urbana", "Urbana", "Urbana", "Rural", "Rural", "Urbana", "Rural", "Urbana", "Rural", "Urbana", "Urbana", "Urbana", "Rural", "Urbana", "Urbana", "Urbana"), Sector = c("Pública", "Pública", "Pública", "Pública", "Pública", "CECE", "Pública", "Pública", "Pública", "Privada", "Pública", "Privada", "Pública", "Pública", "Pública", "Pública", "Pública", "CECE", "Privada", "Pública")), row.names = c(NA, 20L), class = "data.frame") ggplot(est21, aes(as.factor(Sector)))+ geom_bar(width = 0.5, , fill = '#5081ac') + xlab('X') + ylab('Y') + facet_wrap(~Zona) + theme(axis.line = element_line(colour = 'black'), panel.background = element_blank(), axis.text = element_text(size = 18), axis.title = element_text(size = 20), panel.grid.major.y = element_line(colour = 'gray'), panel.grid.minor.y = element_line(colour = 'gray'), plot.title = element_text(hjust = 0.5, size = 20), text = element_text(family = 'Sans')) + scale_y_continuous(expand = c(0, 0), limits = c(0, 7500)) + geom_text(aes(label = scales::percent(prop.table(stat(count)))), stat= "count", vjust = -.5, size = 7) + labs(title = 'Proof')
需求:最终绘制的图形中各个分面使用同一套调色板,目标效果参考下图:
解决方法
你现有代码里直接在geom_bar中写死了固定填充色,导致所有条形都显示为同一种蓝色,无法按类别映射配色。ggplot的色阶是全局生效的,只要把填充色映射到分类变量,再统一指定调色板,所有分面就会自动共用同一套颜色规则,同类别条形在不同分面中颜色完全一致。
修改后的可运行代码如下:
library(ggplot2) ggplot(est21, aes(x = as.factor(Sector), fill = Sector))+ geom_bar(width = 0.5) + # 自定义调色板,按类别名称指定对应颜色即可,可根据自己的需求替换色值 scale_fill_manual(values = c( "Pública" = "#4e79a7", "CECE" = "#f28e2b", "Privada" = "#59a14f" )) + xlab('X') + ylab('Y') + facet_wrap(~Zona) + theme(axis.line = element_line(colour = 'black'), panel.background = element_blank(), axis.text = element_text(size = 18), axis.title = element_text(size = 20), panel.grid.major.y = element_line(colour = 'gray'), panel.grid.minor.y = element_line(colour = 'gray'), plot.title = element_text(hjust = 0.5, size = 20), text = element_text(family = 'Sans')) + # 注意:当前示例测试数据仅20行,因此把y轴上限临时调整为16,你使用自己的全量数据集时改回原有的c(0,7500)即可 scale_y_continuous(expand = c(0, 0), limits = c(0, 16)) + geom_text(aes(label = scales::percent(prop.table(stat(count)))), stat= "count", vjust = -.5, size = 7) + labs(title = 'Proof')
补充说明
- 如果不想手动指定颜色,可以直接替换为预设调色板函数,比如
scale_fill_brewer(palette = "Set2")调用RColorBrewer配色,或者scale_fill_viridis_d()调用viridis色盲友好配色,所有分面会自动匹配统一的颜色映射。 - 原代码
geom_bar参数中多写了一个冗余逗号,修改版中已经删除,避免语法报错。 - 如果运行后发现百分比标签计算的是全样本占比而非分面内占比,可以先手动按Zona分组汇总计数后再传入ggplot绘图,避免stat统计的分组偏差。
内容的提问来源于stack exchange,提问作者Kevin Santos
相关产品推荐
相关产品推荐

