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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.26 23:27:35