Подтвердить что ты не робот

Как динамически обновлять график в цикле в ноутбуке 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.

4b9b3361

Ответ 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())