在函数内创建matplotlib小部件回调
我在Windows上使用Python 2.7。
我有一个函数,这个函数会创建一个带有复选按钮的图形,并且还定义了按钮的回调函数。当我调用这个函数一次的时候,一切都正常,但当我多次调用它时,按钮就不再响应了,具体情况如下:
- 如果图形是用
plt.subplots()
创建的,按钮完全没有反应。 - 如果图形是用
plt.figure()
创建的,情况就不太一致;有时候只有第一个创建的按钮会响应,有时候两个按钮都会响应。
我猜这可能和回调函数的作用范围有关,但我通过反复试验也没能找到具体的问题所在。
示例代码:
import matplotlib.pyplot as plt
from matplotlib.widgets import CheckButtons
def create_button():
plt.subplots() # or: plt.figure()
rax = plt.axes([0.2, 0.2, 0.2, 0.2])
check = CheckButtons(rax, ['on'], [True])
def callback(label):
check.labels[0].set_text('on' if check.lines[0][0].get_visible() else 'off')
plt.draw()
check.on_clicked(callback)
create_button()
#create_button() # uncomment to reproduce problem
plt.show()
2 个回答
1
我觉得如果你在函数的最后加上 return check
,这样可以让按钮在退出时保持活跃状态。
3
问题的关键在于,函数内部创建的 CheckButtons
实例在函数返回后就不再存在了。
我想到的解决办法是,在调用函数的地方保持一个列表(我在一个类里用了一个静态变量),然后在函数内部把这个实例添加到列表中。这样一来,当函数结束时,CheckButtons
实例依然存在。为了避免这个列表变得过大,我还写了一个函数,用来从列表中删除相应的实例,并把这个函数注册为用户关闭窗口时的回调函数。
如果有人对我的解决方案有意见,或者有更符合 Python 风格的建议,我会很高兴听到。