You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.29 23:01:39