多年来,我一直在努力在matplotlib中获得有效的实时绘图,直到今天我仍然不满意。
我想要一个redraw_figure更新图形“实时”(如代码运行)的函数,并且如果我在断点处停止,将显示最新的图。
这是一些演示代码:
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.7FPS)
我可以实现它:
def redraw_figure():
plt.gcf().canvas.flush_events()
plt.show(block=False)
并且它运行得更快(~11FPS),但是当您在断点处停止时,情节不是最新的(例如,如果我在线上放置断点t_start = ...,则不会出现第二个图)。
奇怪的是,实际上工作的是两次调用节目:
def redraw_figure():
plt.gcf().canvas.flush_events()
plt.show(block=False)
plt.show(block=False)
如果你在任何一条线上中断,那么它可以提供~11FPS,并且可以将图表保持为数据。
现在我听说它已经弃用了“block”关键字。并且两次调用相同的函数似乎是一个奇怪的,可能是非便携式的hack。
那么我可以在这个以合理的帧速率绘制的函数中加入什么,不是一个巨大的kludge,最好能在后端和系统中工作?
一些说明:
我在OSX上,并使用TkAgg后端,但欢迎任何后端/系统上的解决方案
交互模式“开启”不起作用,因为它不会实时更新。它只是在解释器等待用户输入时在Python控制台中更新。
一篇博客建议实施:
def redraw_figure():fig = plt.gcf()fig.canvas.draw()fig.canvas.flush_events()
但至少在我的系统上,根本没有重绘图。
所以,如果有人有答案,你会直接让我和其他成千上万的人非常高兴。他们的快乐可能会流向他们的朋友和亲戚,他们的朋友和亲戚等等,这样你就有可能改善数十亿人的生活。
结论
ImportanceOfBeingErnest展示了如何使用blit进行更快的绘图,但它并不像在redraw_figure函数中放置不同的东西那么简单(你需要跟踪要重绘的内容)。
慕桂英4014372
智慧大石