matplotlib调用twinx()后主坐标轴y轴次网格线消失问题
问题背景
需要实现的绘图需求如下:
- 单x轴对应绑定两个独立y轴,展示两组不同量纲的数据
- 显示x轴方向的主网格线
- 主y轴同时显示主网格线与次网格线
实际运行异常表现:仅使用单个y轴时绘图效果完全符合预期,只要取消注释ax2 = ax1.twinx()代码行创建次y轴,主坐标轴的y方向次网格线就会消失。
问题复现代码
import matplotlib.pyplot as plt def plot_graph(x, y1, label1, y2, label2, title): fig, ax1 = plt.subplots() # 绘制第一个y轴对应内容 ax1.set_xlabel('Time (s)') ax1.set_ylabel(label1, color = "red") ax1.grid(which='major',axis='both', color='black', linewidth=1) ax1.grid(which='minor',axis='y', color='gray', linewidth=0.3) ax1.tick_params(axis = 'y') ax1.plot(x, y1, color = "red") # 绑定共享x轴的第二个y轴 ax2 = ax1.twinx() # 问题点:执行这行后主y轴的次网格消失 ax2.set_ylabel(label2, color = 'blue') ax2.plot(x,y2,color = 'blue') ax2.tick_params(axis = 'y') plt.minorticks_on() plt.legend(loc='best') plt.title(title) plt.show() return
问题原因
ax2 = ax1.twinx()执行后,matplotlib会把当前操作的默认轴切换为新创建的ax2,最后调用的全局方法plt.minorticks_on()只会给当前激活的ax2开启次刻度,主y轴ax1并没有开启次刻度。而次网格线必须依托对应方向的次刻度才能渲染,所以之前给ax1设置的y向次网格就显示不出来了。
另外原代码直接调用plt.legend()只会捕获当前激活轴(即ax2)的曲线,会导致ax1的曲线图例丢失,属于双轴图的常见隐藏问题。
修复方法
不要使用全局的plt.minorticks_on(),改为针对ax1单独开启次刻度,同时关闭次y轴的默认网格避免覆盖主y轴的网格设置,另外手动合并两个轴的图例解决显示不全问题,修复后的可运行代码如下:
import matplotlib.pyplot as plt def plot_graph(x, y1, label1, y2, label2, title): fig, ax1 = plt.subplots() # 绘制第一个y轴对应内容 ax1.set_xlabel('Time (s)') ax1.set_ylabel(label1, color="red") # 直接给ax1开启次刻度,保证次网格正常渲染 ax1.minorticks_on() ax1.grid(which='major', axis='both', color='black', linewidth=1) ax1.grid(which='minor', axis='y', color='gray', linewidth=0.3) ax1.tick_params(axis='y') line1 = ax1.plot(x, y1, color="red", label=label1) # 绑定共享x轴的第二个y轴 ax2 = ax1.twinx() ax2.set_ylabel(label2, color='blue') line2 = ax2.plot(x, y2, color='blue', label=label2) ax2.tick_params(axis='y') # 关闭ax2的网格,避免覆盖ax1的网格设置 ax2.grid(False) # 合并两个轴的图例 lines = line1 + line2 labels = [l.get_label() for l in lines] ax1.legend(lines, labels, loc='best') plt.title(title) plt.show() return
内容的提问来源于stack exchange,提问作者Pheytr1x
相关产品推荐
相关产品推荐

