如何在R中为两个不同数据集在柱状图上叠加折线图并添加次坐标轴
解决ggplot2柱状图叠加折线图次坐标轴缩放问题
你当前代码的核心问题是折线图的原始比例数据没有转换到主坐标轴的数值范围——ggplot2的次坐标轴仅负责视觉刻度的映射,不会自动转换数据本身,所以极小的比例值会被主坐标轴的大频率值压缩到底部,导致折线显示异常。
修正方案
- 定义统一的缩放系数,和次坐标轴的运算逻辑对应
- 将折线图的y值乘以该系数,让数据适配主坐标轴的范围
- 次坐标轴通过反向运算(除以该系数)还原为比例刻度
修改后的完整代码
library(ggplot2) a <- rep(seq(2015,2021),2) b <- c(rep('x1',7), rep('x2',7)) c <- c(436, 1230, 1386, 1132, 1096, 756, 474, 24, 46, 110, 88, 66, 148, 96) df_tab <- data.frame(year = a, lab = b, value = c) df_prop <- data.frame(year = seq(2015,2021), value = df_tab$value[df_tab$lab=='x2']/df_tab$value[df_tab$lab=='x1']) # 定义缩放系数,与次轴运算逻辑保持一致 scale_coeff <- 2 * max(df_tab$value) ggplot() + # 柱状图保留原逻辑 geom_bar(data=df_tab, aes(x=year, y=value, fill=lab), stat="identity", position="identity", show.legend=FALSE) + # 折线图y值乘以缩放系数,适配主坐标轴范围 geom_line(data=df_prop, aes(x=year, y=value * scale_coeff), size=1.5, color="red") + # 次坐标轴通过反向运算还原比例刻度 scale_y_continuous( sec.axis = sec_axis(~./scale_coeff, name="proportion"), name="frequency" ) + geom_text(data=df_tab, aes(x=year, y=value, label=value), vjust=0.2, color="black") + scale_fill_manual(name="", values=c("grey80","grey50"), aesthetics = 'fill', labels=c('X1','X2')) + labs(x="") + scale_x_continuous(breaks=seq(2015,2021, by=2)) + theme_classic()
额外优化(可选)
如果需要给折线图添加比例标签,同样要对y值进行转换:
geom_text(data=df_prop, aes(x=year, y=value * scale_coeff, label=round(value, 3)), vjust=-0.5, color="red")
内容的提问来源于stack exchange,提问作者mepstein1218
相关产品推荐
相关产品推荐

