多年来,我一直努力在 matplotlib 中获得高效的实时绘图,直到今天我仍然不满意。
我需要一个 redraw_figure
函数,它可以更新图形“ live”(代码运行时) ,并且如果我在断点处停止,它将显示最新的图形。
下面是一些演示代码:
import time
from matplotlib import pyplot as plt
import numpy as np
def live_update_demo():
plt.subplot(2, 1, 1)
h1 = plt.imshow(np.random.randn(30, 30))
redraw_figure()
plt.subplot(2, 1, 2)
h2, = plt.plot(np.random.randn(50))
redraw_figure()
t_start = time.time()
for i in xrange(1000):
h1.set_data(np.random.randn(30, 30))
redraw_figure()
h2.set_ydata(np.random.randn(50))
redraw_figure()
print 'Mean Frame Rate: %.3gFPS' % ((i+1) / (time.time() - t_start))
def redraw_figure():
plt.draw()
plt.pause(0.00001)
live_update_demo()
当代码运行时,图应该实时更新,我们应该在 redraw_figure()
之后的任何断点处停止时看到最新的数据。问题是如何最好地实现 redraw_figure()
在上面的实现(plt.draw(); plt.pause(0.00001)
)中,它可以工作,但是非常慢(约3.7 FPS)
我可以把它实现为:
def redraw_figure():
plt.gcf().canvas.flush_events()
plt.show(block=False)
它运行速度更快(大约11 FPS) ,但是当您在断点处停止时,绘图不是最新的(例如,如果我在 t_start = ...
行上放置了一个断点,则不会出现第二个绘图)。
奇怪的是,真正起作用的是节目被叫了两次:
def redraw_figure():
plt.gcf().canvas.flush_events()
plt.show(block=False)
plt.show(block=False)
它给出 ~ 11 FPS,并保持图最新数据,如果你在任何行上的突破。
现在我听说“ block”关键字是不推荐的。而且两次调用同一个函数似乎是一种奇怪的,可能是不可移植的黑客行为。
那么,我可以在这个函数中放入什么,使它能够以合理的帧速率绘图,而不是一个巨大的组件,并且最好能够跨后端和系统工作?
一些注意事项:
TkAgg
后端,但任何后端/系统的解决方案都是受欢迎的博客建议实施:
Def repull _ figure () : Fig = plt.gcf () (图片) Flash _ events ()
但至少在我的系统中,这根本不会重新绘制情节。
所以,如果有人有答案,你会直接让我和其他成千上万的人非常高兴。他们的幸福可能会慢慢传递给他们的朋友和亲戚,以及他们的朋友和亲戚,等等,这样你就有可能改善数十亿人的生活。
Import anceOfBeingErnest 展示了如何使用 blit 来实现更快的绘图,但这并不像在 redraw_figure
函数中放入不同的内容那么简单(您需要跟踪要重绘的内容)。