在函数内创建matplotlib小部件回调

2 投票
2 回答
678 浏览
提问于 2025-04-18 17:17

我在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 风格的建议,我会很高兴听到。

撰写回答