如何用ggplot2实现堆叠柱状图+双Y轴带标记折线图(含数据标签)
R语言ggplot2实现堆叠柱状图+双Y轴折线图(带数据标签)
核心实现思路
ggplot2原生对双Y轴支持有限但可通过sec_axis()实现,核心是保证两个数据集的X轴变量完全对齐,同时通过轴转换函数让折线的占比数据适配右侧Y轴刻度。
完整代码示例
假设你的数据集结构如下:
test:包含category(X轴分组)、type(堆叠类别:g/o)、value(柱状图数值)test2:包含category(与test一致)、share(type o的占比,范围0-1)
library(ggplot2) # 1. 绘制基础堆叠柱状图 p <- ggplot() + # 堆叠柱状图:使用test数据集 geom_col(data = test, aes(x = category, y = value, fill = type), position = "stack") + # 2. 设置双Y轴:主Y轴为数值,次Y轴为占比(转换函数根据实际数据调整) scale_y_continuous( name = "数值", # 次Y轴:将主Y轴刻度转换为占比,这里假设最大数值对应100%占比 sec.axis = sec_axis(~ ./max(test$value), name = "Type O占比(%)") ) + # 3. 添加带标记的折线图:使用test2数据集 geom_line(data = test2, aes(x = category, y = share * max(test$value), group = 1), color = "red", linewidth = 1.2) + geom_point(data = test2, aes(x = category, y = share * max(test$value)), color = "red", size = 3) + # 4. 添加折线数据标签 geom_text(data = test2, aes(x = category, y = share * max(test$value), label = paste0(round(share*100,1), "%")), nudge_y = max(test$value)*0.02, # 微调标签位置避免重叠 color = "darkred", size = 3.5) + # 5. 样式调整 labs(x = "类别", fill = "类型") + theme_minimal() + theme( axis.title.y.right = element_text(color = "red"), axis.text.y.right = element_text(color = "red") ) # 输出图表 print(p)
关键细节说明
- 轴转换匹配:折线的
y值需要用share * max(test$value)转换,确保和主Y轴刻度范围一致,这样sec_axis才能正确映射到0-100%的占比刻度。 - 数据集对齐:
test和test2的category必须完全一致(顺序、分组都要对应),否则折线会错位。 - 标签调整:
nudge_y参数可以根据实际数据调整,避免标签和折线/柱子重叠;也可以用position = position_nudge(y = ...)替代。 - 样式区分:通过颜色区分双Y轴的元素,让图表更易读。
内容的提问来源于stack exchange,提问作者Who
相关产品推荐
相关产品推荐

