Как динамически обновлять график в цикле в ноутбуке ipython (в одной ячейке)
Среда: Python 2.7, matplotlib 1.3, IPython notebook 1.1, linux, chrome. Код находится в одной входной ячейке, используя --pylab=inline
Я хочу использовать ноутбук IPython и pandas для использования потока и динамического обновления графика каждые 5 секунд.
Когда я просто использую оператор печати для печати данных в текстовом формате, он отлично работает: выходная ячейка просто сохраняет данные печати и добавляет новые строки. Но когда я пытаюсь построить данные (а затем обновить их в цикле), сюжет никогда не появится в выходной ячейке. Но если я удалю цикл, просто зарисуйте его один раз. Он отлично работает.
Затем я сделал несколько простых тестов:
i = pd.date_range('2013-1-1',periods=100,freq='s')
while True:
plot(pd.Series(data=np.random.randn(100), index=i))
#pd.Series(data=np.random.randn(100), index=i).plot() also tried this one
time.sleep(5)
Выход ничего не покажет, пока я вручную не прерываю процесс (ctrl + m + i). И после того, как я прерываю его, график корректно отображается как несколько перекрывающихся строк. Но то, что я действительно хочу, - это сюжет, который появляется и обновляется каждые 5 секунд (или всякий раз, когда вызывается функция plot()
, как и то, что выдает вывод печати, упомянутый выше, что хорошо работает). Показывать только окончательный график после того, как ячейка полностью выполнена, НЕ является тем, что я хочу.
Я даже попытался явно добавить функцию draw() после каждого plot()
и т.д. Ни один из них не работает. Интересно, как динамически обновлять график с помощью цикла for/while в одной ячейке в ноутбуке IPython.
Ответы
Ответ 1
использовать IPython.display
модуль:
%matplotlib inline
import time
import pylab as pl
from IPython import display
for i in range(10):
pl.plot(pl.randn(100))
display.clear_output(wait=True)
display.display(pl.gcf())
time.sleep(1.0)
Ответ 2
Вы можете улучшить это, добавив wait=True
в clear_output
:
display.clear_output(wait=True)
display.display(pl.gcf())
Ответ 3
Несколько улучшений на HYRY:
- вызовите
display
перед clear_output
чтобы при прерывании ячейки вы clear_output
один график, а не два. - поймайте
KeyboardInterrupt
, чтобы вывод ячейки не был засорен трассировкой.
import matplotlib.pylab as plt
import pandas as pd
import numpy as np
import time
from IPython import display
%matplotlib inline
i = pd.date_range('2013-1-1',periods=100,freq='s')
while True:
try:
plt.plot(pd.Series(data=np.random.randn(100), index=i))
display.display(plt.gcf())
display.clear_output(wait=True)
time.sleep(1)
except KeyboardInterrupt:
break
Ответ 4
Попробуйте добавить show()
или gcf().show()
после функции plot()
. Они заставят текущий показатель обновиться (gcf() возвращает ссылку для текущего рисунка).
Ответ 5
Добавление метки к другим решениям, размещенным здесь, будет продолжать добавлять новые метки в каждом цикле. Чтобы справиться с этим, очистите сюжет с помощью clf
for t in range(100)
if t % refresh_rate == 0:
plt.clf()
plt.plot(history['val_loss'], 'r-', lw=2, label='val')
plt.plot(history['training_loss'], 'b-', lw=1, label='training')
plt.legend()
display.clear_output(wait=True)
display.display(plt.gcf())