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

如何让R语言ggplot2分组柱状图中geom_jitter点显示在对应柱子内

问题修复方案

你遇到的散点错位问题由两个核心配置错误导致,对应修改方法如下:

错误原因

  • 散点图层geom_jitter使用了汇总后的均值数据集df.summary,而非包含所有原始观测值的原始数据集df,无法正确展示每个原始样本的散点
  • 没有使用适配分组躲避场景的散点位置函数,散点没有和对应浓度的柱子进行对齐

修复后的完整代码

library(dplyr)
library(ggplot2)
library(plotly)
library(ggpubr)

df <- data.frame(Sample = c("0.5-1 DMSO (24) CD3-28","0.5-1 DMSO (24) CD3-28","0.5-1 DMSO (24)",
                            "0.5-1 DMSO (24)","1-1 DMSO (24) CD3-28","1-1 DMSO (24) CD3-28",
                            "1-1 DMSO CD3-28","1-1 DMSO","1-1 DMSO (24)","1-1 DMSO (24)","3-1 DMSO",
                            "3-1 DMSO (24)","3-1 DMSO (24)","3-1 DMSO (24) BR","3-1 DMSO (24) BR CD3-28",
                            "3-1 DMSO CD3-28","3-1 DMSO (24) CD3-28","3-1 DMSO (24) CD3-28",
                            "0.5-1 0.1uM  (24) CD3-28","0.5-1 0.1uM  (24) CD3-28","0.5-1 0.1uM (24)",
                            "0.5-1 0.1uM (24)","1-1 0.1uM (24) CD3-28","1-1 0.1uM (24) CD3-28","1-1 0.1uM CD3-28",
                            "1-1 0.1uM","1-1 0.1uM (24)","1-1 0.1uM (24)","3-1 0.1uM","3-1 0.1uM (24)",
                            "3-1 0.1uM (24)","3-1 0.1uM (24) BR","3-1 0.1uM (24) BR CD3-28","3-1 0.1uM CD3-28",
                            "3-1 0.1uM (24) CD3-28","3-1 0.1uM (24) CD3-28","0.5-1  1uM  (24) CD3-28",
                            "0.5-1  1uM  (24) CD3-28","0.5-1 1uM (24)","0.5-1 1uM (24)","1-1 1uM (24) CD3-28",
                            "1-1 1uM (24) CD3-28","1-1 1uM CD3-28","1-1  1uM (24)","1-1  1uM (24)","1-1 1uM",
                            "3-1 1uM","3-1 1uM (24)","3-1 1uM (24)","3-1 1uM (24) BR","3-1  1uM (24) BR CD3-28",
                            "3-1 1uM CD3-28","3-1 1uM (24) CD3-28","3-1 1uM (24) CD3-28"),
                 Group = c("0.5_1 + Stim","0.5_1 + Stim","0.5_1","0.5_1","1_1 + Stim","1_1 + Stim","1_1 + Stim","1_1","1_1","1_1",
                           "3_1","3_1","3_1","3_1 + BR","3_1 + BR","3_1 + Stim","3_1 + Stim","3_1 + Stim","0.5_1 + Stim","0.5_1 + Stim",
                           "0.5_1","0.5_1","1_1 + Stim","1_1 + Stim","1_1 + Stim","1_1","1_1","1_1","3_1","3_1","3_1","3_1 + BR",
                           "3_1 + BR","3_1 + Stim","3_1 + Stim","3_1 + Stim","0.5_1 + Stim","0.5_1 + Stim","0.5_1","0.5_1","1_1 + Stim",
                           "1_1 + Stim","1_1 + Stim","1_1","1_1","1_1","3_1","3_1","3_1","3_1 + BR","3_1 + BR","3_1 + Stim","3_1 + Stim","3_1 + Stim"),
                 Concentration = c("DMSO","DMSO","DMSO","DMSO","DMSO","DMSO","DMSO","DMSO","DMSO","DMSO","DMSO","DMSO","DMSO","DMSO",
                                   "DMSO","DMSO","DMSO","DMSO","0.1uM","0.1uM","0.1uM","0.1uM","0.1uM","0.1uM","0.1uM","0.1uM","0.1uM",
                                   "0.1uM","0.1uM","0.1uM","0.1uM","0.1uM","0.1uM","0.1uM","0.1uM","0.1uM","1uM","1uM","1uM","1uM",
                                   "1uM","1uM","1uM","1uM","1uM","1uM","1uM","1uM","1uM","1uM","1uM","1uM","1uM","1uM"),
                 Marker = c(29.1,35.5,20,11.8,48.9,41.2,19.4,2.49,21.6,17.7,5.52,51.5,42.5,8.5,45.2,17.1,
                            67,58.5,42.7,36.4,16,22.4,42.2,50.3,33.4,5.88,27.9,21.5,22.9,62.5,35.3,17,50.4,
                            49,65.2,65.3,52.9,37.3,19.1,16.1,52.7,46.5,45.1,30.9,28.9,6.62,13.1,87.4,52.1,19.8,63.7,55.3,88.4,66.4))

# 先将原始数据的浓度列转为因子,保证分组顺序正确
df$Concentration <- factor(df$Concentration, levels=c("DMSO","0.1uM","1uM"))

df.summary <- df %>%
  dplyr::group_by(Sample, Group, Concentration) %>%
  dplyr::summarize(sd = sd(Marker, na.rm = TRUE), Marker = mean(Marker), .groups = "drop")

p <- ggplot(data = df.summary, aes(x = Group, y = Marker, fill = Concentration)) + 
  geom_bar(stat="identity", position=position_dodge(.9))  +
  # 散点使用原始数据,位置用jitterdodge对齐分组柱子
  geom_jitter(data = df, aes(x = Group, y = Marker), 
              position = position_jitterdodge(jitter.width = 0.2, dodge.width = 0.9), 
              color = "black") + 
  geom_errorbar(aes(ymin = Marker - sd, ymax = Marker + sd), 
                width = 0.2, position=position_dodge(0.9)) +
  scale_fill_manual(values = c("DMSO" = '#619CFF',"0.1uM" = '#F8766D',"1uM" = '#00BA38')) + 
  theme_bw()
p <- ggpar(p, x.text.angle = 45)
ggplotly(p)

关键修改说明

  • 给原始数据集的Concentration列设置因子顺序,保证分组、填充色和柱子顺序匹配
  • 散点图层切换为使用原始数据集df,位置函数替换为position_jitterdodge,设置dodge.width=0.9和柱子的躲避宽度一致实现跨分组对齐,jitter.width=0.2控制同一柱子内散点的抖动幅度,避免超出柱子范围
  • 移除误差棒映射中冗余的df.summary$前缀,避免环境变量引用错误

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.01 14:15:06