matplotlib 事件的退出递归

Posted

技术标签:

【中文标题】matplotlib 事件的退出递归【英文标题】:Exit recursion for matplotlib events 【发布时间】:2020-05-03 13:07:57 【问题描述】:

我有一个带有button_press_event 的matplotlib 小图。 在监听器内部,我使用plt.pause 为每次点击制作一个简短的动画。 这可以正常工作并且符合预期。 但是,如果我在动画结束之前再次单击,我会进入递归并在最后播放剩余的动画。如果你点击的速度足够快,你甚至可以到达RecursionError

我需要更改什么,所以新的点击会丢弃on_click 方法中的所有剩余步骤?

import numpy as np
import matplotlib.pyplot as plt
fig = plt.figure()
ax = fig.subplots()

ax.set_xlim(0, 10)
ax.set_ylim(0, 10)

xy = np.random.random(2)*10
h1 = ax.plot(xy[0], xy[1], marker='x', color='k')[0]
h2 = ax.plot(xy[0], xy[1], marker='o', color='r')[0]

def on_click(event):
    h1.set_xdata(event.xdata)
    h1.set_ydata(event.ydata)
    for i in range(10):
        h2.set_xdata(event.xdata+np.random.random()-0.5)
        h2.set_ydata(event.ydata+np.random.random()-0.5)
        plt.pause(0.1)

cid_click = fig.canvas.mpl_connect('button_press_event', on_click)

【问题讨论】:

【参考方案1】:

您可以使用FuncAnimation。然后确保在新动画开始之前停止并删除以前的动画。

import numpy as np
import matplotlib.pyplot as plt
from matplotlib.animation import FuncAnimation

fig, ax = plt.subplots()

ax.set_xlim(0, 10)
ax.set_ylim(0, 10)

xy = np.random.random(2)*10
h1 = ax.plot(xy[0], xy[1], marker='x', color='k')[0]
h2 = ax.plot(xy[0], xy[1], marker='o', color='r')[0]

anis = []
def on_click(event):
    h1.set_xdata(event.xdata)
    h1.set_ydata(event.ydata)
    def animate(i):
        h2.set_xdata(event.xdata+np.random.random()-0.5)
        h2.set_ydata(event.ydata+np.random.random()-0.5)
    for ani in anis:
        ani.event_source.stop()
        anis.remove(ani)
        del ani
    anis.append(FuncAnimation(fig, animate, frames=10, repeat=False))
    fig.canvas.draw_idle()

cid_click = fig.canvas.mpl_connect('button_press_event', on_click)

plt.show()

【讨论】:

以上是关于matplotlib 事件的退出递归的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 matplotlib blitting 将 matplot.patches 添加到 wxPython 中的 matplotlib 图?

python matplot怎么画箭头

matplot绘图

python matplot怎么设置rgb

matplot绘图

Python访问街区所有节点最短路径问题,并结合matplotlib可视化