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
相关产品推荐
相关产品推荐

