2015-12-28 14 views
45

Nelle risposte a how to dynamically update a plot in a loop in ipython notebook (within one cell), viene fornito un esempio di come aggiornare dinamicamente un grafico all'interno di un taccuino Jupyter all'interno di un loop Python. Tuttavia, questo funziona distruggendo e ricreando la trama su ogni iterazione, e un commento in uno dei thread nota che questa situazione può essere migliorata usando la magia new-ish %matplotlib nbagg, che fornisce una figura interattiva incorporata nel notebook, piuttosto che un'immagine statica.Qual è il modo attualmente corretto per aggiornare dinamicamente i grafici in Jupyter/iPython?

Tuttavia, questa meravigliosa nuova funzionalità nbagg sembra completamente non documentata per quanto posso dire, e non riesco a trovare un esempio di come usarlo per aggiornare dinamicamente un grafico. Quindi la mia domanda è, , come si aggiorna in modo efficiente un grafico esistente in un notebook Jupyter/Python, usando il backend nbagg? Poiché aggiornare dinamicamente i grafici in matplotlib è un problema complesso in generale, un semplice esempio di lavoro sarebbe di enorme aiuto. Un puntatore a qualsiasi documentazione sull'argomento sarebbe anche estremamente utile.

Per essere chiari cosa sto chiedendo: quello che voglio fare è eseguire un codice di simulazione per alcune iterazioni, quindi tracciare un grafico del suo stato corrente, quindi eseguirlo per qualche altra iterazione, quindi aggiornare la trama per riflettere lo stato attuale e così via. Quindi l'idea è di tracciare una trama e quindi, senza alcuna interazione da parte dell'utente, aggiornare i dati nella trama senza distruggere e ricreare il tutto.

Ecco un codice leggermente modificato dalla risposta alla domanda collegata sopra, che lo ottiene ridisegnando l'intera figura ogni volta. Voglio ottenere lo stesso risultato, ma in modo più efficiente 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) 

risposta

39

Ecco un esempio che aggiorna un grafico in un ciclo. Aggiorna i dati nella figura e non ridisegna l'intera figura ogni volta. Blocca l'esecuzione, anche se sei interessato a eseguire una serie finita di simulazioni e a salvare i risultati da qualche parte, potrebbe non essere un problema per te.

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

I put this up on nbviewer here.

C'è un IPython Widget version of nbagg that is currently a work in progress at the Matplotlib repository. Quando sarà disponibile, probabilmente sarà il modo migliore per utilizzare nbagg.

MODIFICA: aggiornato per mostrare più trame

+1

Ottimo, sembra funzionare bene. La mancanza di interattività mentre è in esecuzione non è un grosso problema per me. Una cosa un po 'strana: se cambio 'while True:' in un ciclo for, quando termina il loop ottengo due immagini statiche dell'ultimo grafico, piuttosto che un nbagg interattivo. Qualche idea del perché? – Nathaniel

+0

Ho cambiato il tempo in un ciclo for e l'ho provato su tmpnb.org, ma non vedo una seconda immagine o una perdita di interattività. Girato al buio, ma si potrebbe provare a spostare il ciclo intorno alla chiamata alla funzione, piuttosto che avere il ciclo nella funzione. per f nella gamma (10): pltsin (ax) time.sleep (1) – pneumatics

+0

Come si fa a trama due linee sovrapposti insieme su questo terreno? – jfhc

Problemi correlati