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

如何用ggplot绘制按Race/Sex/Language分组的柱状图并添加显著性标记?

问题:ggplot实现分组聚合的x轴布局并添加显著性标记

我有如下结构的DataFrame:

# dput输出
structure(list(Group = structure(c(1L, 5L, 2L, 3L, 4L, 6L, 7L, 
8L, 9L), levels = c("White", "NA", "Other Race", "Two Races", 
"Asian", "Female", "Male", "Mandarin", "Spanish"), class = "factor"), 
    emmean = c(1.8, 2.1, 1.5, 1.9, 1.6, 1.7, 2, 1.4, 1.9), SE = c(0.4, 
    0.5, 0.3, 0.5, 0.4, 0.4, 0.5, 0.4, 0.5), df = c(22483, 22483, 22483, 22483, 22483, 22483, 22483, 22483, 22483), lower.CL = c(1.3, 
    1.2, 1, 1.5, 1.2, 1.3, 1.6, 1.1, 1.5), upper.CL = c(2.3, 
    2.4, 1.8, 2.3, 1.9, 2, 2.5, 1.8, 2.3), Measure = c("Measure", 
    "Measure", "Measure", "Measure", "Measure", "Measure", "Measure", 
    "Measure", "Measure"), fill = c("Race", "Race", "Race", "Race", 
    "Race", "Sex", "Sex", "Language", "Language")), row.names = c(6L, 
7L, 8L, 9L, 10L, 13L, 14L, 17L, 18L), class = "data.frame")

尝试用以下ggplot代码绘制按Race、Sex、Language分组的柱状图,但生成的图表未实现分类组聚合的x轴布局,希望得到分组样式,同时在Asian与参考组White之间添加显著性标记(如星号):

ggplot(plot_data_custom, aes(x = Group, y = emmean, fill = fill)) +
  geom_bar(stat = "identity", position = position_dodge(width = 0.7), width = 0.7, color = "black") +
  geom_errorbar(aes(ymin = lower.CL, ymax = upper.CL), position = position_dodge(width = 0.7), width = 0.2, color = "black") +
  labs(title = "Measure", y = "Adjusted Value", x = NULL) +
  scale_fill_manual(values = professional_palette, limits = legend_order) +
  scale_y_continuous(limits = c(0, 3.5), breaks = seq(0, 3.5, by = 0.5)) +
  theme_bw() +
  theme(legend.position = "bottom",
        axis.text.x = element_text(angle = 45, hjust = 1),
        panel.grid.major = element_line(color = "lightgray", size = 0.2),
        panel.grid.minor = element_blank(),
        axis.line = element_line(color = "black"),
        plot.title = element_text(face = "bold", size = 14),
        legend.text = element_text(size = 10),
        legend.key.size = unit(1.5, "lines"),
        plot.margin = unit(c(1, 1, 1, 1), "cm")) +
  guides(fill = guide_legend(title = NULL))

解决方案

1. 实现x轴分组聚合布局

要将Race、Sex、Language三类分组展示,推荐使用facet_wrap按fill字段分栏,同时调整Group的因子顺序,确保同类别的分组排列合理:

# 重新指定Group的因子顺序,按类别聚合排列
plot_data_custom$Group <- factor(plot_data_custom$Group,
                                 levels = c("White", "Asian", "NA", "Other Race", "Two Races",
                                            "Female", "Male",
                                            "Mandarin", "Spanish"))

分面后每个类别会作为独立栏位,x轴仅显示对应类别下的分组,无需再用position_dodge。

2. 添加显著性标记

通过geom_segment和geom_text手动添加White与Asian之间的显著性星号,也可以使用ggsignif包简化操作,这里给出基础ggplot实现方式:

# 定义显著性标记的位置数据
signif_data <- data.frame(
  x = 1, xend = 2,  # White和Asian在Race分栏中的x轴位置
  y = 2.5, yend = 2.5,  # 标记线的y轴高度
  fill = "Race",
  label = "*"  # 显著性标记
)

完整可运行代码
library(ggplot2)

# 调整Group因子顺序
plot_data_custom$Group <- factor(plot_data_custom$Group,
                                 levels = c("White", "Asian", "NA", "Other Race", "Two Races",
                                            "Female", "Male",
                                            "Mandarin", "Spanish"))

# 定义显著性标记数据
signif_data <- data.frame(
  x = 1, xend = 2,
  y = 2.5, yend = 2.5,
  fill = "Race",
  label = "*"
)

# 绘制图表
ggplot(plot_data_custom, aes(x = Group, y = emmean, fill = fill)) +
  geom_bar(stat = "identity", width = 0.7, color = "black") +
  geom_errorbar(aes(ymin = lower.CL, ymax = upper.CL), width = 0.2, color = "black") +
  # 添加显著性标记的横线和星号
  geom_segment(data = signif_data, aes(x = x, xend = xend, y = y, yend = yend), color = "black") +
  geom_text(data = signif_data, aes(x = (x+xend)/2, y = y + 0.1, label = label), size = 6) +
  labs(title = "Measure", y = "Adjusted Value", x = NULL) +
  # 自定义填充色,可替换为你需要的professional_palette
  scale_fill_manual(values = c("Race" = "#1f77b4", "Sex" = "#ff7f0e", "Language" = "#2ca02c"), 
                    limits = c("Race", "Sex", "Language")) +
  scale_y_continuous(limits = c(0, 3), breaks = seq(0, 3, by = 0.5)) +
  # 分面实现分组布局,free_x让每个分栏的x轴独立
  facet_wrap(~fill, scales = "free_x", nrow = 1) +
  theme_bw() +
  theme(legend.position = "bottom",
        axis.text.x = element_text(angle = 45, hjust = 1),
        panel.grid.major = element_line(color = "lightgray", size = 0.2),
        panel.grid.minor = element_blank(),
        axis.line = element_line(color = "black"),
        plot.title = element_text(face = "bold", size = 14),
        legend.text = element_text(size = 10),
        legend.key.size = unit(1.5, "lines"),
        plot.margin = unit(c(1, 1, 1, 1), "cm"),
        # 去掉分面标题,图例已展示类别信息
        strip.text = element_blank()) +
  guides(fill = guide_legend(title = NULL))

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.01 17:22:52