如何在ggplot中绘制双Y轴折线图展示数值差异大的变量
双Y轴解决数值差异导致的绘图问题
问题描述
现有数据集如下:
| 日期 | Mn | Fe |
|---|---|---|
| 2013-01-13 | 67.7 | 1990 |
| 2014-01-13 | 60.8 | 2082 |
| 2015-01-13 | 57.1 | 3901 |
| 2016-01-13 | 40.8 | 7022 |
| 2017-01-13 | 30.8 | 5063 |
| 2018-01-13 | 50.3 | 2032 |
| 2019-01-13 | 20.8 | 6225 |
| 2020-01-13 | 43.1 | 8853 |
| 2021-01-13 | 53.8 | 4048 |
| 2022-01-13 | 33.1 | 6238 |
使用以下ggplot代码绘图时,因Mn数值远小于Fe,Mn线条近乎直线,需创建独立双Y轴展示两个变量的变化趋势:
t <- ggplot(data = stack.data, aes(x= Date)) + geom_line(aes (y = Mn,color = "Mn"), size = 1.4) + geom_line(aes (y = Fe, color = "Fe"), size = 1.4) + scale_y_continuous(name = "Mn", sec.axis = sec_axis(trans = ~.*10, name="Fe"))+ scale_color_manual("", values = c( "#F8766D", "#00BFC4")) + theme_bw()+ theme(legend.position="top") t
解决方案
原代码的核心问题是未对Fe的原始数值做缩放,双轴转换逻辑错误。正确思路是先将Fe的数值缩小到Mn的量级,再通过双轴转换还原原始刻度:
修改后的代码
# 确保Date列是日期格式(若原始数据不是则执行) stack.data$Date <- as.Date(stack.data$Date) # 定义缩放系数,两种方式可选: # 1. 手动指定(根据数据量级,这里Fe约为Mn的100倍) scale_factor <- 100 # 2. 动态计算(让Fe和Mn的最大值在图中对齐) # scale_factor <- max(stack.data$Fe) / max(stack.data$Mn) t <- ggplot(data = stack.data, aes(x= Date)) + # Mn使用原始数值绘制 geom_line(aes(y = Mn, color = "Mn"), size = 1.4) + # Fe数值除以缩放系数,缩小到Mn的量级 geom_line(aes(y = Fe / scale_factor, color = "Fe"), size = 1.4) + # 左侧Y轴对应Mn,右侧Y轴通过乘以缩放系数还原Fe的原始刻度 scale_y_continuous( name = "Mn", sec.axis = sec_axis(trans = ~.*scale_factor, name = "Fe") ) + scale_color_manual("", values = c("#F8766D", "#00BFC4")) + theme_bw() + theme(legend.position = "top") t
说明
- 缩放Fe的数值后,其范围与Mn匹配,两条线的波动都能清晰展示。
- 右侧Y轴的转换公式会将缩放后的数值还原为Fe的原始数值,保证刻度准确。
- 动态计算缩放系数的方式能让两个变量的最大值在图中处于同一高度,更便于对比波动幅度。
内容的提问来源于stack exchange,提问作者Sankar Manalilkada Sasidharan
相关产品推荐
相关产品推荐

