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

ggplot中geom_bar(position="dodge")与误差条偏移异常问题排查

Fixing the "Ghost Stacking" & Error Bar Issues in Your ggplot Bar Chart

Hey there! Let's break down why you're seeing that weird overlapping/stacked look in your bar chart, even with position = "dodge" set up.

The Root Cause

Looking at your sample data (from the dput output), I notice your dataset is grouped by Agneau, and for each Agneau, you have multiple rows per Level-Statut pair. When you use geom_bar(stat="identity"), ggplot automatically sums up all the Pos.Area values in the same x (Level) and fill (Statut) group. Since you have multiple rows (one per Agneau) for each group, it's stacking those values without you realizing it—hence the "ghost stacking" effect. The error bars are also repeating for every row in the group, making them look messy.

The Fix: Summarize Your Data First

You need to collapse your data into one row per Level-Statut group, calculating the summary values you want to plot (like the mean Pos.Area, and your error bounds). Here's how to do it with dplyr:

Step 1: Ungroup & Summarize Your Data

First, we'll remove the existing grouping by Agneau, then calculate the stats per Level-Statut pair:

# Load dplyr if you haven't already
library(dplyr)

# Ungroup the data to reset grouping
GFAPdata_ungrouped <- ungroup(GFAPdata_numb)

# Create a summarized dataset: one row per Level + Statut
GFAPdata_summary <- GFAPdata_ungrouped %>%
  group_by(Level, Statut) %>%
  summarise(
    # Use the mean of Pos.Area for each group
    Pos.Area = mean(Pos.Area),
    # If your existing lower/higher are group-level stats, use first() to grab them
    lower = first(lower),
    higher = first(higher),
    .groups = "drop" # Remove grouping after summarizing
  )

Step 2: Plot with the Summarized Data

Now use this cleaned-up dataset to build your chart—no more stacking, and error bars will display correctly:

ggplot(GFAPdata_summary, aes(x=Level, y=Pos.Area, fill=Statut))+ 
  geom_bar(stat="identity", color="black", position = "dodge")+ 
  geom_errorbar(aes(ymin=lower, ymax=higher), width=.2, position=position_dodge(.9))

Optional: Recalculate Error Bars Properly

If your original lower/higher values were calculated per Agneau instead of per Level-Statut, you should recalculate them for the group to get accurate error bars:

GFAPdata_summary <- GFAPdata_ungrouped %>%
  group_by(Level, Statut) %>%
  summarise(
    Pos.Area = mean(Pos.Area),
    # Calculate SEM (standard error of the mean)
    SEM = sd(Pos.Area)/sqrt(n()),
    # Set error bounds as mean ± SEM
    lower = Pos.Area - SEM,
    higher = Pos.Area + SEM,
    .groups = "drop"
  )

# Replot with the corrected error bars
ggplot(GFAPdata_summary, aes(x=Level, y=Pos.Area, fill=Statut))+ 
  geom_bar(stat="identity", color="black", position = "dodge")+ 
  geom_errorbar(aes(ymin=lower, ymax=higher), width=.2, position=position_dodge(.9))

This works because now each Level-Statut combination has exactly one row of data—ggplot will draw one bar per group, no hidden stacking, and error bars will only appear once per bar.

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.30 05:29:08