Каков в настоящее время правильный способ динамического обновления участков в Jupyter/iPython?


ответы как динамически обновить участок в цикле в IPython notebook (в пределах одной ячейки), приведен пример динамического обновления графика внутри записной книжки Jupyter в цикле Python. Однако это работает путем уничтожения и повторного создания графика на каждой итерации, и комментарий в одном из потоков отмечает, что эта ситуация может быть улучшена с помощью new-ish %matplotlib nbagg магия, которая обеспечивает интерактивную фигуру, встроенную в ноутбук, а не чем статическое изображение.

однако, это замечательное новое nbagg функция кажется полностью недокументированной, насколько я могу судить, и я не могу найти пример того, как использовать ее для динамического обновления сюжета. Таким образом мой вопрос, как эффективно обновить существующий участок в ноутбуке Jupyter / Python, используя бэкэнд nbagg? поскольку динамическое обновление графиков в matplotlib является сложной проблемой в целом, простой рабочий пример будет огромной помощью. Один указатель на любую документацию по этой теме также был бы чрезвычайно полезен.

чтобы быть ясным, что я прошу: то, что я хочу сделать, это запустить некоторый код моделирования для нескольких итераций, затем нарисовать график его текущего состояния, затем запустить его еще на несколько итераций, а затем обновить график, чтобы отразить текущее состояние, и так далее. Поэтому идея состоит в том, чтобы нарисовать сюжет, а затем, без какого-либо взаимодействия с пользователем, обновить данные в сюжете, не разрушая и не воссоздавая целое вещь.

вот немного измененный код из ответа на связанный вопрос выше, который достигает этого путем повторного рисования всей фигуры каждый раз. Я хочу добиться такого же результата, но более эффективно, используя nbagg.

%matplotlib inline
import time
import pylab as pl
from IPython import display
for i in range(10):
    pl.clf()
    pl.plot(pl.randn(100))
    display.display(pl.gcf())
    display.clear_output(wait=True)
    time.sleep(1.0)
2   52  

2 ответа:

вот пример, который обновляет график в цикле. Он обновляет данные на рисунке и не перерисовывает всю фигуру каждый раз. Он блокирует выполнение, хотя если вы заинтересованы в запуске конечного набора симуляций и сохранении результатов где-то, это может не быть проблемой для вас.

%matplotlib notebook

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

def pltsin(ax, colors=['b']):
    x = np.linspace(0,1,100)
    if ax.lines:
        for line in ax.lines:
            line.set_xdata(x)
            y = np.random.random(size=(100,1))
            line.set_ydata(y)
    else:
        for color in colors:
            y = np.random.random(size=(100,1))
            ax.plot(x, y, color)
    fig.canvas.draw()

fig,ax = plt.subplots(1,1)
ax.set_xlabel('X')
ax.set_ylabel('Y')
ax.set_xlim(0,1)
ax.set_ylim(0,1)
for f in range(5):
    pltsin(ax, ['b', 'r'])
    time.sleep(1)

Я поставил это на nbviewer здесь.

есть IPython виджет версия nbagg то есть в настоящее время ведется работа Репозиторий Matplotlib. Когда это будет доступно, это, вероятно, будет лучший способ использовать nbagg.

изменить: обновлено, чтобы показать несколько участков

Я использую jupyter-lab и это работает для меня (адаптировать его к вашему случаю):

from IPython.display import clear_output
from matplotlib import pyplot as plt
import collections
%matplotlib inline

def live_plot(data_dict, figsize=(7,5), title=''):
    clear_output(wait=True)
    plt.figure(figsize=figsize)
    for label,data in data_dict.items():
        plt.plot(data, label=label)
    plt.title(title)
    plt.grid(True)
    plt.xlabel('epoch')
    plt.legend(loc='center left') # the plot evolves to the right
    plt.show();

затем в цикле вы заполняете словарь и передаете его в live_plot():

data = collections.defaultdict(list)
for i in range(100):
    data['foo'].append(np.random.random())
    data['bar'].append(np.random.random())
    data['baz'].append(np.random.random())
    live_plot(data)

убедитесь, что у вас есть несколько ячеек ниже графика, в противном случае вид защелкивается на месте каждый раз, когда график перерисовывается.