Я заметил, что каждое решение для построения непрерывно обновляемых данных (я обнаружил) с непрерывно увеличивающейся длиной имеет одну огромную задержку: если данных нет сразу, окно 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()
Этот код прекрасно работает без сбора данных для цикла в функции animate, но при этом окно графика зависает. Возьмите это также:
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 минут.
EDIT:
После дальнейшего тестирования можно использовать FuncAnimation
, но он очень хакерский и все еще немного сломан. Если вы увеличите interval
до ожидаемого времени animate
, оно будет работать, но каждый раз, когда вы перемещаете или масштабируете график, все данные исчезают до следующего обновления. Поэтому, когда у вас есть вид, вы не можете его коснуться.
Edit:
Для ясности изменен сон на цикл for