ggplot2绘制双Y轴次轴刻度异常及图例显示问题
问题核心原因
- 原代码次轴配置
sec_axis(~.)未做数值线性映射:ggplot2的双Y轴本质是主Y轴的刻度变换,不会自动对齐两个字段的数值范围,直接使用恒等变换会导致次轴刻度和主轴完全一致,次轴对应的点线位置完全错位。 - 原代码将填充、颜色参数写在
aes()外部,不会触发ggplot2的图例生成逻辑,因此无法正常显示图例。
修复后可运行代码
library(ggplot2) # 自动计算双轴缩放系数,避免硬编码适配数据变化 main_axis_max <- max(payout_yeild_loss$`Payout (GDD)`, na.rm = TRUE) sec_axis_max <- max(payout_yeild_loss$yield_loss_ratio_1, na.rm = TRUE) scale_coef <- main_axis_max / sec_axis_max fig_GDD <- payout_yeild_loss %>% ggplot() + # 主Y轴柱状图,将fill属性放入aes用于生成图例 geom_col(aes(x = year, y = `Payout (GDD)`, fill = "GDD Payout")) + # 次Y轴点、线:原始数值*缩放系数,适配主Y轴坐标范围,color属性放入aes生成图例 geom_point(aes(x = year, y = yield_loss_ratio_1 * scale_coef, color = "Yield loss ratio"), size = 3, shape = 15) + geom_line(aes(x = year, y = yield_loss_ratio_1 * scale_coef, color = "Yield loss ratio"), size = 1) + scale_y_continuous( name = "Payout (RM/°C)", # 次轴反向转换:将主Y轴刻度还原为次轴原始数值 sec.axis = sec_axis(~ . / scale_coef, name = "Yield loss ratio (%)"), expand = c(0.01, 0) ) + scale_x_date( date_breaks = "2 year", date_labels = "%Y", expand = c(0.01, 0) ) + # 手动指定映射对应的颜色 scale_fill_manual(values = c("GDD Payout" = "black")) + scale_color_manual(values = c("Yield loss ratio" = "red")) + labs( x = NULL, fill = "Indicator", color = "Indicator" ) + theme_classic() + # 可按需调整图例位置 theme(legend.position = "top") # 输出图表 print(fig_GDD)
关键注意点
- 双Y轴缩放逻辑:所有图层实际都绘制在主Y轴坐标系中,次轴仅为主轴刻度的线性转换标签,不存在独立坐标空间。必须将次轴对应字段的数值按两个轴的最大值比例缩放至主轴区间,再通过次轴的变换公式反向还原刻度标签,才能保证数值位置和刻度完全对应。
- 图例生成逻辑:只有将颜色、填充、形状等图形属性作为映射关系写入
aes()内部,ggplot2才会自动生成对应图例,在aes()外直接指定固定属性值不会生成图例,后续可通过scale_*_manual系列函数自定义映射对应的实际视觉参数。
内容的提问来源于stack exchange,提问作者Mukhtar Abdi
相关产品推荐
相关产品推荐

