为了账号安全,请及时绑定邮箱和手机立即绑定

Matplotlib / PyPlot中的快速实时绘图

Matplotlib / PyPlot中的快速实时绘图

ibeautiful 2019-09-02 10:11:03
多年来,我一直在努力在matplotlib中获得有效的实时绘图,直到今天我仍然不满意。我想要一个redraw_figure更新图形“实时”(如代码运行)的函数,并且如果我在断点处停止,将显示最新的图。这是一些演示代码:import timefrom matplotlib import pyplot as pltimport numpy as npdef 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函数中放置不同的东西那么简单(你需要跟踪要重绘的内容)。
查看完整描述

3 回答

?
慕桂英4014372

TA贡献1871条经验 获得超13个赞

这是进行实时绘图的一种方法:将绘图作为图像阵列,然后将图像绘制到多线程屏幕。


使用pyformulas屏幕(~30 FPS)的示例:


import pyformulas as pf

import matplotlib.pyplot as plt

import numpy as np

import time


fig = plt.figure()


screen = pf.screen(title='Plot')


start = time.time()

for i in range(10000):

    t = time.time() - start


    x = np.linspace(t-3, t, 100)

    y = np.sin(2*np.pi*x) + np.sin(3*np.pi*x)

    plt.xlim(t-3,t)

    plt.ylim(-3,3)

    plt.plot(x, y, c='black')


    # If we haven't already shown or saved the plot, then we need to draw the figure first...

    fig.canvas.draw()


    image = np.fromstring(fig.canvas.tostring_rgb(), dtype=np.uint8, sep='')

    image = image.reshape(fig.canvas.get_width_height()[::-1] + (3,))


    screen.update(image)


#screen.close()

免责声明:我是pyformulas的维护者


查看完整回答
反对 回复 2019-09-02
?
智慧大石

TA贡献1946条经验 获得超3个赞

我认为看看这与matplotlib FuncAnimation的比较会有所帮助。由于这也绘制了matplotlib figure(fig.canvas.draw()),它肯定不会更快

查看完整回答
反对 回复 2019-09-02
  • 3 回答
  • 0 关注
  • 3329 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信