В течение многих лет я изо всех сил пытался получить эффективный живой сюжет в 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" устарело. И вызов одной и той же функции дважды кажется странным, вероятно, не-переносным хаком в любом случае.
Итак, что я могу поместить в эту функцию, которая будет строить с разумной частотой кадров, не является гигантским kludge и предпочтительно будет работать через бэкэнды и системы?
Некоторые примечания:
- Я нахожусь в OSX и использую
TkAgg
бэкэнд, но решения на любом бэкэнд/системе приветствуются - Интерактивный режим "On" не будет работать, потому что он не обновляется вживую. Он просто обновляется, когда на консоли Python, когда интерпретатор ждет ввода пользователя.
- A блог предложил реализацию:
def redraw_figure():
fig = plt.gcf()
fig.canvas.draw()
fig.canvas.flush_events()
Но, по крайней мере, в моей системе, которая вообще не перерисовывает графики.
Итак, если у кого-то есть ответ, вы бы прямо сделали меня и тысячи других счастливыми. Их счастье, вероятно, просочится к их друзьям и родственникам, их друзьям и родственникам и т.д., Чтобы вы могли улучшить жизнь миллиардов.
Выводы
ImportanceOfBeingErnest показывает, как вы можете использовать blit для более быстрого построения графика, но это не так просто, как положить что-то другое в функцию redraw_figure
(вам нужно следить за тем, что нужно перерисовывать).