I am trying to add a button to toolbar
. The button is a custom class that inherits ToolToggleBase
. In my custom SelectButton
class, I want to pass few arguments, but I getting an error:
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
tm.add_tool("CustomButton", SelectButton(fig, ax))
fig.canvas.manager.toolbar.add_tool(tm.get_tool("CustomButton"), "toolgroup")
return fig, ax
class SelectButton(ToolToggleBase):
default_toggled = False
def __init__(self, fig1, ax1, *args, **kwarg):
super().__init__(*args, **kwarg)
print("fig: ", fig1)
print("ax: ", ax1)
x = [1, 2, 3]
fig, ax = simple_plot(x)
plt.show()
Results in:
super().init(*args, **kwargs) TypeError: init() missing 2 required positional arguments: 'toolmanager' and 'name'
However, if I do not pass any arguments and pass only the class name, everything works as expected:
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
tm.add_tool("CustomButton", SelectButton)
fig.canvas.manager.toolbar.add_tool(tm.get_tool("CustomButton"), "toolgroup")
return fig, ax
class SelectButton(ToolToggleBase):
default_toggled = False
def __init__(self, *args, **kwarg):
super().__init__(*args, **kwarg)
x = [1, 2, 3]
fig, ax = simple_plot(x)
plt.show()
I understand I must call add_tool
wrong when use an instance of a class rather then the class name, but I fail to understand what am I supposed to do if I want to pass arguments to SelectButton
class.
You need to pass the class SelectButton
itself, not an instance SelectButton()
of it to add_tool
. You should pass the additional parameters as kwargs
:
def simple_plot(mat):
fig = plt.figure()
ax = fig.add_subplot()
# ...
tm = fig.canvas.manager.toolmanager
tm.add_tool("CustomButton", SelectButton, fig=fig, ax=ax)
fig.canvas.manager.toolbar.add_tool(tm.get_tool("CustomButton"), "toolgroup")
return fig, ax
class SelectButton(ToolToggleBase):
default_toggled = False
def __init__(self, *args, fig, ax, **kwarg):
super().__init__(*args, **kwarg)
print("fig: ", fig)
print("ax: ", ax)
This prints:
fig: Figure(640x480)
ax: Axes(0.125,0.11;0.775x0.77)
If you for some reason really want to use args
instead of kwargs
you should use a partial as shown in the other answer. Passing only the first 2 args to super and using the rest by yourself is more a hack than a solution as it depends on matplotlib's implementation details:
tm.add_tool("CustomButton", SelectButton, fig, ax)
def __init__(self, *args, **kwarg):
super().__init__(*args[:2], **kwarg)
print("fig: ", args[2])
print("ax: ", args[3])