matplotlib 动画与 python 事件循环(事件循环给出不稳定的结果)

问题描述 投票:0回答:1

matplotlib FuncAnimation 计时器的工作效果明显优于 python 事件循环或主线程 while 循环。

我有一个脚本,可以将 UDP 缓冲区发送到微控制器来控制 LED。我使用 matplotlib 绘制和“模拟”这些 LED,并且还可以在 FunAnimation 回调中发送 UDP 缓冲区。

当在 FuncAnimation Timer 回调中发送 udp 数据包时,可以顺利、及时地接收该数据包。当使用 python 事件循环、线程或简单的睡眠/while 循环时,它是不一致且不稳定的。

这是 matplotlib FunAnimation 代码的编辑示例(效果很好):

# matplotlib use case
def update(_):
    send_udp_buffer()
    return scat # scatter plot of LEDs

ani = animation.FuncAnimation(
    fig=fig,
    func=update,
    frames=60,
    interval=50, # 50 milliseconds
)

这是我尝试过的基于通用 while 循环的代码的示例(最终结果不稳定且不一致):

# Standard while-loop
while True:
    send_udp_buffer()
    time.sleep(.05)

# python event-loop

import asyncio

async def periodic():
    while True:
        send_udp_buffer()
        await asyncio.sleep(0.05)

loop = asyncio.new_event_loop()
asyncio.set_event_loop(loop)
task = loop.create_task(periodic())

我使用的是 MacOSX,所以 FuncAnimation 使用的 Timer 是 TimerMac,它是 NSTimer 的包装。我尝试过包含并利用它,但似乎存在一些隐藏的实现细节。

我的问题

为什么事件循环的行为方式与 matplotlib 计时器不同,我如何复制这种行为?

python matplotlib timer udp nstimer
1个回答
0
投票

对于任何好奇的人,我找到了答案。

我的假设是错误的,FuncAnimation 并不比其他方法更好或更流畅。 FuncAnimation 实际上并不使用提供给它的间隔。它保持在100ms左右。由于 UDP 数据包之间的延迟,FuncAnimation 看起来更好,所以我的 50 毫秒延迟太激进了。

但是,如果有人对在 python 中使用 NSTimer 感到好奇,有一个包装 obj-c 类的库,

pyobjc

© www.soinside.com 2019 - 2024. All rights reserved.