双y轴图需共享x轴、独立缩放y轴,通过twinx()创建右轴并分别设置标签、刻度、图例;绘图必须明确指定轴对象,避免plt.plot()误用;数据需校验有效性,jupyter中应启用tight_layout和高dpi。

双Y轴图的核心逻辑是共享X轴但独立缩放Y轴
Matplotlib本身不提供“双Y轴”对象,而是通过twinx()方法在原坐标系上叠加一个共享X轴、独立Y轴的新坐标系。关键在于两个轴的数据不能混用——比如左侧画温度(℃),右侧必须画湿度(%)或风速(m/s),否则量纲冲突会误导解读。
常见错误是调用twinx()后忘记为右侧轴单独设置标签、刻度或图例,导致图形信息缺失或坐标轴重叠遮挡。
- 必须对左右两轴分别调用
set_ylabel(),否则右侧轴默认无标签 - 若右侧数据范围极小(如0.01~0.05),
plt.ylim()需显式设置,否则自动缩放可能显示为0.0 - 图例要用
ax1.legend(loc='upper left')和ax2.legend(loc='upper right')分开指定位置,避免重叠
正确创建双Y轴并绘制不同量级数据
先用plt.subplots()获取主轴ax1,再用ax1.twinx()生成右轴ax2。注意:所有绘图操作必须明确作用于对应轴对象,不能直接用plt.plot()——那会默认画在最后激活的轴上,极易出错。
import matplotlib.pyplot as plt
import numpy as np
<p>x = np.linspace(0, 10, 50)
y1 = np.sin(x) <em> 100 # 量级 ~ ±100
y2 = np.cos(x) </em> 0.03 # 量级 ~ ±0.03</p><p>fig, ax1 = plt.subplots()
ax2 = ax1.twinx() # 创建右Y轴</p><p>ax1.plot(x, y1, 'b-', label='Temperature (℃)')
ax2.plot(x, y2, 'r--', label='Humidity (%)')</p><p>ax1.set_xlabel('Time')
ax1.set_ylabel('Temperature (℃)', color='b')
ax2.set_ylabel('Humidity (%)', color='r')
ax1.tick_params(axis='y', labelcolor='b')
ax2.tick_params(axis='y', labelcolor='r')</p><p>ax1.legend(loc='upper left')
ax2.legend(loc='upper right')
plt.show()</p>
当右侧数据含NaN或非数值时图表崩溃怎么办
twinx()本身不校验数据类型,但一旦ax2.plot()传入含np.nan或字符串的数组,Matplotlib会静默跳过无效点,但若整列都是NaN,ax2.get_ylim()可能返回(0, 1)这种无意义范围,导致右侧轴压缩成一条线。
- 绘制前用
np.isfinite(y2).any()检查右侧数据是否有效 - 若含NaN,用
y2_clean = y2[np.isfinite(y2)]过滤后再绘图 - 避免用
pandas.Series.plot()直接调twinx()——它内部可能触发自动ylim重算,建议转为numpy.array再画
双Y轴图在Jupyter中显示模糊或图例错位
Jupyter默认使用inline后端,DPI较低且不支持动态重绘。调用twinx()后若未及时刷新坐标系状态,可能出现右侧Y轴刻度挤在一起、图例文字被截断等问题。
- 在绘图代码末尾加
plt.tight_layout(),强制重排子图间距 - 提高输出质量:
plt.rcParams['figure.dpi'] = 150(放在导入matplotlib之后) - 若仍错位,改用
fig.savefig('plot.png', dpi=300, bbox_inches='tight')导出再查看,绕过inline渲染缺陷
双Y轴真正的难点不在代码长度,而在于确保两个Y轴的物理意义可比、刻度标签不误导、且任意一方数据异常时图形仍能稳定呈现——这些都得靠手动校验,没法靠库自动兜底。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!











