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

Matplotlib工具栏添加带参数自定义ToolToggleBase按钮报错问询

如何给Matplotlib的ToolToggleBase子类传递自定义参数

问题原因

你遇到的报错核心原因:

  • ToolToggleBase的__init__方法必须接收toolmanager和name两个必填参数,这两个参数是由ToolManager在创建工具实例时自动传入的。
  • 你直接传递SelectButton(fig, ax)给add_tool,相当于提前创建了实例,此时没有传入toolmanager和name,导致父类初始化时缺失必要参数。
  • 仅传递类名时,ToolManager会自动调用类的__init__并传入toolmanager和name,因此能正常运行。

解决方案

方法1:调整__init__参数顺序,通过关键字传递自定义参数

将toolmanager和name作为__init__的前两个参数,自定义参数放在后面,在add_tool中通过关键字参数传递自定义值:

import numpy as np
import matplotlib.pyplot as plt
plt.rcParams["toolbar"] = "toolmanager"
from matplotlib.backend_tools import ToolToggleBase


def simple_plot(mat):
    fig = plt.figure()
    ax = fig.add_subplot()
    ax.plot(np.reshape(mat, [-1, 1]))
    ax.grid(True)
    ax.legend()
    tm = fig.canvas.manager.toolmanager
    # 用关键字参数传递自定义的fig和ax
    tm.add_tool("CustomButton", SelectButton, fig1=fig, ax1=ax)
    fig.canvas.manager.toolbar.add_tool(tm.get_tool("CustomButton"), "toolgroup")
    return fig, ax


class SelectButton(ToolToggleBase):
    default_toggled = False

    # 优先声明toolmanager和name参数,再接自定义参数
    def __init__(self, toolmanager, name, fig1, ax1, **kwargs):
        super().__init__(toolmanager, name, **kwargs)
        self.fig = fig1
        self.ax = ax1
        print("fig: ", fig1)
        print("ax: ", ax1)


x = [1, 2, 3]
fig, ax = simple_plot(x)
plt.show()

方法2:使用类工厂函数绑定参数

如果不想调整参数顺序,可以用工厂函数动态生成绑定了自定义参数的子类:

import numpy as np
import matplotlib.pyplot as plt
plt.rcParams["toolbar"] = "toolmanager"
from matplotlib.backend_tools import ToolToggleBase


def create_select_button(fig, ax):
    # 内部类绑定外部的fig和ax
    class SelectButton(ToolToggleBase):
        default_toggled = False

        def __init__(self, toolmanager, name, **kwargs):
            super().__init__(toolmanager, name, **kwargs)
            self.fig = fig
            self.ax = ax
            print("fig: ", fig)
            print("ax: ", ax)
    return SelectButton


def simple_plot(mat):
    fig = plt.figure()
    ax = fig.add_subplot()
    ax.plot(np.reshape(mat, [-1, 1]))
    ax.grid(True)
    ax.legend()
    tm = fig.canvas.manager.toolmanager
    # 传入绑定了参数的类
    tm.add_tool("CustomButton", create_select_button(fig, ax))
    fig.canvas.manager.toolbar.add_tool(tm.get_tool("CustomButton"), "toolgroup")
    return fig, ax


x = [1, 2, 3]
fig, ax = simple_plot(x)
plt.show()

原理说明

  • ToolManager.add_tool的第二个参数需要是工具类(而非实例),调用该方法时,ToolManager会自动创建类的实例,并传入toolmanager(自身)和name(工具名称)作为前两个初始化参数。
  • 额外的位置参数或关键字参数会被传递给类的__init__方法,因此只需确保自定义参数的声明在toolmanager和name之后,或者通过工厂函数提前绑定参数即可。

内容的提问来源于stack exchange,提问作者Alon123

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.18 01:05:08