Каков в настоящее время правильный способ динамического обновления участков в 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 ответа:
вот пример, который обновляет график в цикле. Он обновляет данные на рисунке и не перерисовывает всю фигуру каждый раз. Он блокирует выполнение, хотя если вы заинтересованы в запуске конечного набора симуляций и сохранении результатов где-то, это может не быть проблемой для вас.
%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)
убедитесь, что у вас есть несколько ячеек ниже графика, в противном случае вид защелкивается на месте каждый раз, когда график перерисовывается.