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

如何在ggplot中按分组(而非条件)为分组条形图着色?

在ggplot2中实现按年代区分颜色、按条件分组的条形图

你需要创建分组条形图,x轴为decade,y轴为rate,按condition分隔条形,且不同decade使用不同颜色。之前的代码因映射逻辑问题未达到预期效果,以下是几种可行的解决方案:

方法1:用填充颜色区分年代,线条样式区分条件

这种方法让同一年代的两个条形共享主色调,通过线条样式区分Yes/No条件,视觉上清晰区分年代和条件:

library(ggplot2)

df <- data.frame (decade  = c("1970", "1970","1980", "1980","1990","1990","2000","2000"),
                  condition = c("Yes", "No", "Yes","No","Yes","No","Yes","No"),
                  rate = c(60,34,50,25,24,12,9,5))

ggplot(df, aes(x = decade, y = rate, fill = decade, linetype = condition)) +
  geom_bar(position = "dodge", stat = "identity", color = "black") +
  scale_fill_brewer(palette = "Set1") + # 可选:使用预定义配色方案
  labs(x = "年代", y = "比率", fill = "年代", linetype = "条件") +
  theme_minimal()

逻辑说明:

  • 将fill映射为decade,确保同一年代的条形颜色一致
  • 用linetype映射condition,通过实线/虚线区分Yes/No
  • 添加color="black"是为了让线条样式更明显

方法2:自定义同色系深浅区分条件,年代用不同主色

如果希望同一年代的两个条件有细微颜色差异,可通过交互变量自定义配色:

library(ggplot2)

# 自定义配色:每个年代对应深浅两种颜色
decade_colors <- c(
  "1970_Yes" = "#1f77b4", "1970_No" = "#aec7e8",
  "1980_Yes" = "#ff7f0e", "1980_No" = "#ffbb78",
  "1990_Yes" = "#2ca02c", "1990_No" = "#98df8a",
  "2000_Yes" = "#d62728", "2000_No" = "#ff9896"
)

ggplot(df, aes(x = decade, y = rate, fill = interaction(decade, condition))) +
  geom_bar(position = "dodge", stat = "identity") +
  scale_fill_manual(
    values = decade_colors,
    labels = c("1970-Yes", "1970-No", "1980-Yes", "1980-No", 
               "1990-Yes", "1990-No", "2000-Yes", "2000-No"),
    name = "分组"
  ) +
  labs(x = "年代", y = "比率") +
  theme_minimal()

逻辑说明:

  • 使用interaction(decade, condition)创建组合分组变量
  • 手动为每个组合分配同色系的深浅颜色,既区分年代,又区分条件

方法3:用图案区分条件(需ggpattern包)

如果希望保持年代颜色完全一致,用图案区分条件,可借助ggpattern包:

# 先安装包:install.packages("ggpattern")
library(ggplot2)
library(ggpattern)

ggplot(df, aes(x = decade, y = rate, fill = decade, pattern = condition)) +
  geom_bar_pattern(
    position = "dodge", stat = "identity",
    pattern_fill = "black", pattern_density = 0.1
  ) +
  scale_fill_brewer(palette = "Set1") +
  scale_pattern_manual(values = c(Yes = "none", No = "stripe")) +
  labs(x = "年代", y = "比率", fill = "年代", pattern = "条件") +
  theme_minimal()

逻辑说明:

  • fill映射decade保证同年代颜色一致
  • pattern映射condition,用无图案/条纹区分Yes/No

原代码问题分析

你之前的代码中fill=condition将填充颜色绑定到了条件,color=decade仅设置条形边框颜色,因此无法看到年代对应的填充效果。调整美学映射的绑定对象,就能实现需求。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.21 13:35:22