I need to generate a variable number (total) of button widgets in matplotlib and have each one store a different number in the variable, var.
import matplotlib.pyplot as plt
from matplotlib.widgets import Button as BT
total = 4
class Index:
ind = 0
def plot_pick(self, event):
var=event
print(var)
ax_chooseplot={}
chooseplot_BT={}
callback=Index()
for i in range(0,total):
loc=0.95-i*0.03
ax_chooseplot[i] = plt.axes([loc-0.002, 0.87, 0.02, 0.03])
chooseplot_BT[i] = BT(ax_chooseplot[i], '')
chooseplot_BT[i].on_clicked(callback.plot_pick(i))
plt.show()
This code prints i sequentially then on pressing any button:
TypeError: 'NoneType' object is not callable
It seems like the function "plot_pick" is being called during the for loop and then the value of i is being discarded?
I've seen this issue addressed for tkinter buttons but I've been unable to apply those answers to matplotlib embedded buttons. Is there an easy way to solve this?
CodePudding user response:
The issue comes from the way you are passing the i
argument to your plot_pick
function. Passing it directly to your function won't work. A possible alternative is to use functools.partial
. You can find below an example where I use functools.partial
to print the index of the button that was clicked on:
import matplotlib.pyplot as plt
from matplotlib.widgets import Button as BT
import functools
total = 4
class Index:
ind = 0
def plot_pick(self,i, event):
print('Button ' str(i))
ax_chooseplot={}
chooseplot_BT={}
callback=Index()
for i in range(0,total):
loc=0.95-i*0.03
ax_chooseplot[i] = plt.axes([loc-0.002, 0.87, 0.02, 0.03])
chooseplot_BT[i] = BT(ax_chooseplot[i], str(i))
chooseplot_BT[i].on_clicked(functools.partial(callback.plot_pick,i))
plt.show()