I have a code that uses matplotlib and the Button widget. It all works well, but when this code is written as a function, the buttons stop working. This is because after the function runs, the button objects are being removed by the garbage collector.
Here is an example of the code that does not work well:
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.widgets import Button
def fun():
def Prev(x):
print("Prev")
def Next(x):
print("Next")
freqs = np.arange(2, 20, 3)
fig, ax = plt.subplots()
plt.subplots_adjust(bottom=0.2)
t = np.arange(0.0, 1.0, 0.001)
s = np.sin(2*np.pi*freqs[0]*t)
l, = plt.plot(t, s, lw=2)
axprev = plt.axes([0.7, 0.05, 0.1, 0.075])
axnext = plt.axes([0.81, 0.05, 0.1, 0.075])
bnext = Button(axnext, 'Next')
bnext.on_clicked(Next)
bprev = Button(axprev, 'Previous')
bprev.on_clicked(Prev)
fun()
Here is my non-so-elegant solution:
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.widgets import Button
def fun():
def Prev(x):
print("Prev")
def Next(x):
print("Next")
freqs = np.arange(2, 20, 3)
fig, ax = plt.subplots()
plt.subplots_adjust(bottom=0.2)
t = np.arange(0.0, 1.0, 0.001)
s = np.sin(2*np.pi*freqs[0]*t)
l, = plt.plot(t, s, lw=2)
axprev = plt.axes([0.7, 0.05, 0.1, 0.075])
axnext = plt.axes([0.81, 0.05, 0.1, 0.075])
bnext = Button(axnext, 'Next')
bnext.on_clicked(Next)
bprev = Button(axprev, 'Previous')
bprev.on_clicked(Prev)
return bnext,bprev
b1,b2=fun()
Is there a better, best-practice solution for this kind of problem?