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

如何在ggplot2中绘制含前后时间点数据的叠加分组柱状图

搞定ggplot2叠加分组柱状图的问题

我明白你想要的效果:每个问题(pain/fear)下,展示before时间点不同答案的分组柱状图,同时加上after时间点的黑色计数柱状图进行对比。你的现有代码问题出在数据结构没梳理清晰,以及geom_bar的位置映射没设置对,我来帮你一步步修正:

第一步:优化数据预处理

首先我们把数据整理成更清晰的结构,把原来的question列拆分成时间(before/after)和问题类型(pain/fear),这样后续绘图更方便:

library(dplyr)
library(ggplot2)
library(tidyr)

# 原始数据
df <- data.frame(
  before_fear=c(1,1,1,2,3),
  before_pain=c(2,2,1,3,1),
  after_fear=c(1,3,3,2,3),
  after_pain=c(1,1,2,3,1)
)

# 转换为长格式并整理字段
df_long <- df %>%
  gather(key = "question", value = "answer_option") %>%
  group_by(question, answer_option) %>%
  summarise(n = n(), .groups = "drop") %>% # 按问题和答案计数
  mutate(
    time = factor(ifelse(grepl("before", question), "before", "after"), 
                  levels = c("before", "after")), # 设定时间顺序
    type = gsub("before_|after_", "", question), # 提取问题类型(pain/fear)
    answer_option = factor(answer_option) # 转换为因子保证顺序
  )

第二步:绘制目标图表

现在我们用两个geom_bar分别绘制before和after的数据,通过position_dodge让它们在同一问题下并列展示,同时给after的数据设置黑色填充:

ggplot() +
  # 绘制before数据:按答案分组的彩色柱状图
  geom_bar(
    data = filter(df_long, time == "before"),
    aes(x = type, y = n, fill = answer_option),
    position = position_dodge(width = 0.7), # 分组柱状的间距
    width = 0.7,
    stat = "identity"
  ) +
  # 绘制after数据:黑色柱状图,和before的分组柱状并列
  geom_bar(
    data = filter(df_long, time == "after"),
    aes(x = type, y = n),
    position = position_dodge(width = 0.7), # 和before用相同的dodge参数保证对齐
    width = 0.3, # 设置更窄的宽度,避免重叠
    stat = "identity",
    fill = "black"
  ) +
  # 调整图例和标签
  scale_fill_discrete(name = "Before Answer") +
  labs(
    x = "Question Type",
    y = "Count",
    title = "Before vs After Question Responses"
  ) +
  # 手动添加after的图例项(让黑色柱状有对应的图例说明)
  annotate("rect", xmin = -Inf, xmax = Inf, ymin = -Inf, ymax = -Inf, 
           fill = "black", color = NA) +
  guides(
    fill = guide_legend(order = 1),
    color = guide_legend(title = "After", override.aes = list(fill = "black"))
  ) +
  theme_classic()

关键说明

  • 我们把x轴设置为问题类型(pain/fear),而不是原始的before_fear这类字段,这样能让before和after的数据在同一问题下对比,更直观。
  • 通过position_dodge(width = 0.7)让before的分组柱状和after的黑色柱状对齐并列,调整width参数可以控制柱状的宽窄,避免重叠。
  • 如果想要让after的柱状叠加在before的柱状上方(而不是并列),只需要把position_dodge换成position_stack即可。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.29 07:17:41