ggplot双折线图:如何将prop2映射至右侧次坐标轴?
解决ggplot双Y轴线条不匹配次坐标轴的问题
问题出在ggplot的次坐标轴只是视觉层面的刻度映射,直接用prop2的原始值绘图,它只会匹配左侧主坐标轴的刻度,不会自动适配右侧次轴。要让prop2的线条对应右侧次轴,得先把prop2的数值转换到主坐标轴的范围里,再通过次轴的逆转换还原显示。
修正步骤:
明确两个轴的范围
- 主Y轴(prop1):
[0, 0.6] - 次Y轴(prop2):
[0.1, 0.25]
- 主Y轴(prop1):
定义数值转换/逆转换函数
把prop2的数值映射到主Y轴的范围,同时给次轴做逆转换来显示正确刻度:# 转换函数:prop2 -> 主Y轴刻度范围 trans_prop2_to_main <- function(x) { (x - 0.1) / (0.25 - 0.1) * (0.6 - 0) + 0 } # 逆转换函数:主Y轴刻度 -> prop2原始范围,用于次轴显示 trans_main_to_prop2 <- function(x) { x / (0.6 - 0) * (0.25 - 0.1) + 0.1 }修改绘图代码
绘制prop2时使用转换后的值,次轴调用逆转换函数,并设置对应刻度:ggplot(df) + aes(x = type) + # prop1的点和线,正常绘制 geom_point(aes(y = prop1), size = 2) + geom_line(aes(y = prop1), size = 1, group = 1) + # prop2的点和线,使用转换后的值 geom_point(aes(y = trans_prop2_to_main(prop2)), size = 2, shape = 15) + geom_line(aes(y = trans_prop2_to_main(prop2)), size = 1, group = 1) + theme_bw() + labs(x = "") + scale_y_continuous( name = "prop1\n", breaks = seq(0,0.6,0.1), limits = c(0,0.6), labels = function(x) paste0(x * 100, "%"), # 次轴使用逆转换函数,设置刻度和名称 sec.axis = sec_axis( trans = trans_main_to_prop2, name = "prop2", breaks = seq(0.1, 0.25, 0.05), labels = function(x) paste0(x * 100, "%") ) )
关键点说明:
- 必须手动做数值转换,因为ggplot的次轴不会自动帮你缩放数据,它只是把主轴的刻度重新计算显示而已。
- 转换函数里的范围要和你设定的轴范围严格对应,否则会出现偏移。
内容的提问来源于stack exchange,提问作者Artur Vidaurre de Almeida
相关产品推荐
相关产品推荐

