Matplotlib实时图能够处理两次数据更新之间的长时间

时间:2019-07-11 06:09:59

标签: python matplotlib

我注意到,绘制长度不断增加的不断更新的数据(我发现)的每个解决方案都有一个巨大的挫折-如果没有立即出现数据,则matplotlib窗口会冻结(例如没有响应)。以这个为例:

from matplotlib import pyplot as plt
from matplotlib import animation
from random import randint
from time import sleep
fig = plt.figure()
ax = fig.add_subplot(1,1,1)
line, = ax.plot([])
x = []
y = []
def animate(i):
    x.append(i)
    y.append(randint(0,10))
    for i in range(100000000):
        # Do calculations to attain next data point
        pass
    line.set_data(x, y)
    return line,

anim = animation.FuncAnimation(fig, animate,
                               frames=200, interval=20, blit=True)
plt.show()

此代码可以很好地运行,而无需在动画函数中进行循环的数据获取,但是在该窗口中冻结了图形窗口。还要注意这一点:

plt.ion()
x = []

for i in range(1000):
    x.append(randint(0,10))
    for i in range(100000000):
        # Do calculations to attain next data point
        pass
    plt.plot(x)
    plt.pause(0.001)

也冻结。 (为此,感谢上帝,因为使用该方法无法关闭边界线,因为图表不断在所有内容面前弹出。我不建议您删除睡眠)

这也是:

plt.ion()
x = []

for i in range(1000):
    x.append(randint(0,10))
    for i in range(100000000):
        # Do calculations to attain next data point
        pass
    plt.plot(x)
    plt.draw()
    plt.pause(0.001)
    plt.clf()

也是这样:(从https://stackoverflow.com/a/4098938/9546874复制)

import matplotlib.pyplot as plt
import numpy as np
from time import sleep
x = np.linspace(0, 6*np.pi, 100)
y = np.sin(x)

# You probably won't need this if you're embedding things in a tkinter plot...
plt.ion()

fig = plt.figure()
ax = fig.add_subplot(111)
line1, = ax.plot(x, y, 'r-') # Returns a tuple of line objects, thus the comma

for phase in np.linspace(0, 10*np.pi, 500):
    line1.set_ydata(np.sin(x + phase))
    for i in range(100000000):
        # Do calculations to attain next data point
        pass
    fig.canvas.draw()
    fig.canvas.flush_events()

这是一个很大的问题,因为天真地认为所有数据都将以一致的间隔出现。我只想要一个图表,该图表在数据到来时会更新,并且不会在停机期间崩溃。请记住,数据之间的间隔可能会更改,可能是2秒或5分钟。

编辑:

经过进一步测试,可以使用FuncAnimation,但是它非常笨拙,并且仍然有些破损。如果将interval增加到animate的预期时间以上,则可以使用,但是每次平移或缩放图形时,所有数据都会消失,直到下一次更新。因此,一旦有了视图,就无法触摸。

编辑:

为了清晰起见,将睡眠更改为for循环

2 个答案:

答案 0 :(得分:1)

更新的答案: 问题在于数据获取或生成以及matplotlib窗口在同一线程上运行,因此前者阻止了后者。为了克服这个问题,将数据采集移到一个单独的过程中,如this example所示。除了进程和管道,您还可以使用线程和队列。

答案 1 :(得分:0)

请参见此示例,了解睡眠情况,效果很好:

= ^ .. ^ =

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


fig, ax = plt.subplots()
x = np.arange(0, 2*np.pi, 0.01)
line, = ax.plot(x)


def animate(i):
    y_data = 0
    for j in range(10):
        y_data = np.random.uniform(-1, j, 1)

    line.set_ydata(y_data)
    plt.pause(1)
    return line,


ani = animation.FuncAnimation(
    fig, animate, interval=2, blit=True, save_count=50)


plt.ylim(-2, 11)
plt.show()