Environnement: Python 2.7, matplotlib 1.3, IPython notebook 1.1, linux, chrome. Le code est dans une seule cellule d'entrée, en utilisant --pylab=inline
Je veux utiliser IPython notebook et pandas pour consommer un flux et mettre à jour de manière dynamique un tracé toutes les 5 secondes.
Lorsque je viens d'utiliser l'instruction print pour imprimer les données au format texte, cela fonctionne parfaitement: la cellule de sortie conserve uniquement l'impression des données et l'ajout de nouvelles lignes. Mais lorsque j'essaie de tracer les données (puis de les mettre à jour en boucle), le tracé n'apparaît jamais dans la cellule de sortie. Mais si je supprime la boucle, tracez-la une seule fois. Ça fonctionne bien.
Ensuite, j'ai fait un test simple:
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)
La sortie ne montrera rien jusqu'à ce que j'interrompe manuellement le processus (ctrl + m + i). Et après l’interrompre, le graphique montre correctement que plusieurs lignes se chevauchent. Mais ce que je veux vraiment, c’est un tracé qui s'affiche et est mis à jour toutes les 5 secondes (ou chaque fois que la fonction plot()
est appelée, tout comme l’instruction d’impression que j’ai mentionnée ci-dessus, qui fonctionne bien). Afficher uniquement le graphique final une fois la cellule complétée n’est PAS ce que je veux.
J'ai même essayé d'ajouter explicitement la fonction draw () après chaque plot()
, etc. Aucun d'entre eux ne fonctionne. Vous demandez-vous comment mettre à jour de manière dynamique un tracé par une boucle for/while dans une cellule dans le cahier IPython.
utilisation IPython.display
module:
%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)
Vous pouvez améliorer cela en ajoutant wait=True
à clear_output
:
display.clear_output(wait=True)
display.display(pl.gcf())
Quelques améliorations sont sur réponse de HYRY :
display
avant clear_output
afin que vous vous retrouviez avec une parcelle plutôt que deux lorsque la cellule est interrompue.KeyboardInterrupt
, de sorte que la sortie de la cellule ne soit pas encombrée par le suivi.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
Essayez d'ajouter show()
ou gcf().show()
après la fonction plot()
. Ceux-ci forceront la mise à jour de la figure actuelle (gcf () retourne une référence pour la figure actuelle).
Ajouter une étiquette aux autres solutions publiées ici continuera à ajouter de nouvelles étiquettes à chaque boucle. Pour résoudre ce problème, effacez le tracé en utilisant 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())