You need to enable JavaScript to run this app. ggplot2分组柱状图中如何让geom_smooth()趋势线对齐所属组的柱子
优惠活动
大模型
产品
解决方案
定价
更多

ggplot2分组柱状图中如何让geom_smooth()趋势线对齐所属组的柱子

错位的核心原因

两个图层的位置规则不统一:

  • geom_col 用了dodge错位逻辑,会把同一年份下A、B、C三组的柱子按固定宽度左右错开,每个类别都有自己专属的x轴偏移位置
  • geom_smooth 默认用的是无偏移的位置规则,直接在原始x轴刻度的中心位置画趋势线,完全不会跟随柱子的错位走,所有类别的线全堆在x轴中心,自然对不齐柱子。
对齐方法

只需要给geom_smooth套上和柱子完全一致的dodge偏移规则,就能自动把每个类别的趋势线挪到对应柱子的正上方,实现起止位置和同组柱子对齐。
调整时要保证两个图层的偏移宽度、柱子宽度完全一致,不然会出现细微错位。

修正后的可运行代码
library(tidyverse)

set.seed(9)

data <- data.frame(Cat=c(rep("A",times=5),rep("B",times=5),rep("C", times=5)),
                   year=rep(c(2015,2016,2017,2018,2019),times=3),
                   count=c(sample(seq(60,80),replace=TRUE,size=5),
                           sample(seq(100,140),replace=TRUE,size=5),
                           sample(seq(20,30),replace=TRUE,size=5)))

legend_labels <- c("A","B","C")
# 统一配置柱子与偏移宽度,避免图层间参数不匹配
bar_width <- 0.9

ggplot(data=data,aes(x=year, y=count, fill=Cat, color=Cat)) +
  geom_col(position = position_dodge(width = bar_width), 
           show.legend = TRUE, width = bar_width) + 
  geom_smooth(method="lm", formula=y~x, se=FALSE, 
              show.legend=TRUE, linetype="dashed",
              position = position_dodge(width = bar_width)) +
  scale_fill_manual(values = c("#CF232B","#942192","#000000"),
                    labels=legend_labels) +
  scale_color_manual(values= c("#CF232B","#942192","#000000"),
                     labels=paste("Trend ",legend_labels,sep="")) +
  theme(panel.background = element_rect(fill="white"),
        legend.title = element_blank(),
        legend.key = element_rect(fill="white")) +
  guides(color=guide_legend(override.aes=list(fill=NA)),
         fill=guide_legend(override.aes = list(linetype=0)))
常见踩坑提示
  • 两个图层的dodge宽度必须和柱子本身宽度一致,要是手动改了柱子粗细,记得同步更新bar_width变量
  • 不要给geom_smooth单独设dodge宽度却不对应柱子宽度,不然会出现趋势线偏到相邻柱子上方的错位问题

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.22 11:54:06