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
相关产品推荐
相关产品推荐

