¿Cuál es la forma correcta actual de actualizar dinámicamente los gráficos en Jupyter / iPython?

En las respuestas a cómo actualizar dinámicamente un gráfico en un bucle en un cuaderno ipython (dentro de una celda) , se proporciona un ejemplo de cómo actualizar dinámicamente un gráfico dentro de un cuaderno Jupyter dentro de un bucle de Python. Sin embargo, esto funciona destruyendo y recreando la ttwig en cada iteración, y un comentario en uno de los subprocesos señala que esta situación se puede mejorar utilizando la magia new-ish %matplotlib nbagg , que proporciona una figura interactiva incrustada en el Cuaderno, en lugar de una imagen estática.

Sin embargo, esta nueva característica maravillosa de nbagg parece estar completamente sin documentar, por lo que puedo decir, y no puedo encontrar un ejemplo de cómo usarlo para actualizar dinámicamente un gráfico. Por lo tanto, mi pregunta es, ¿cómo se actualiza de manera eficiente una ttwig existente en un cuaderno Jupyter / Python, utilizando el backend de nbagg? Dado que la actualización dinámica de las plots en matplotlib es un tema difícil en general, un simple ejemplo de trabajo sería una gran ayuda. Un indicador de cualquier documentación sobre el tema también sería extremadamente útil.

Para que quede claro lo que estoy pidiendo: lo que quiero hacer es ejecutar un código de simulación para algunas iteraciones, luego dibujar un gráfico de su estado actual, luego ejecutarlo durante unas pocas iteraciones más y luego actualizar el gráfico para reflejar El estado actual, y así sucesivamente. Entonces, la idea es dibujar un gráfico y luego, sin ninguna interacción del usuario, actualizar los datos en el gráfico sin destruir y recrear todo.

Aquí hay un código ligeramente modificado de la respuesta a la pregunta vinculada anterior, que logra esto al volver a dibujar toda la figura cada vez. Quiero lograr el mismo resultado, pero más eficientemente usando 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) 

Aquí hay un ejemplo que actualiza una ttwig en un bucle. Actualiza los datos en la figura y no vuelve a dibujar toda la figura cada vez. No bloquea la ejecución, aunque si está interesado en ejecutar un conjunto finito de simulaciones y guardar los resultados en algún lugar, puede que no sea un problema para usted.

 %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) 

Pongo esto en nbviewer aquí.

Hay una versión de nbagg IPython Widget que actualmente es un trabajo en progreso en el repository de Matplotlib . Cuando esté disponible, esa será probablemente la mejor manera de usar nbagg .

EDIT: actualizado para mostrar múltiples plots

Estoy usando jupyter-lab y esto funciona para mí (adáptalo a tu caso):

 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(); 

Luego, en un bucle, llena un diccionario y lo pasa a 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) 

asegúrese de tener algunas celdas debajo de la ttwig, de lo contrario, la vista se ajustará en su lugar cada vez que se vuelva a dibujar la ttwig.