J'essaie de tracer certaines données d'une caméra en temps réel en utilisant OpenCV. Cependant, le traçage en temps réel (en utilisant matplotlib) ne semble pas fonctionner.
J'ai isolé le problème dans cet exemple simple:
fig = plt.figure()
plt.axis([0, 1000, 0, 1])
i = 0
x = list()
y = list()
while i < 1000:
temp_y = np.random.random()
x.append(i)
y.append(temp_y)
plt.scatter(i, temp_y)
i += 1
plt.show()
Je m'attendrais à ce que cet exemple trace 1000 points individuellement. Ce qui se passe réellement, c'est que la fenêtre apparaît avec le premier point affiché (ok avec ça), puis attend que la boucle se termine avant de remplir le reste du graphique.
Avez-vous des raisons pour lesquelles je ne vois pas de points remplis un à la fois?
plt.axis()
mais créez plutôt deux listes x et y et appelezplt.plot(x,y)
2. dans votre boucle, ajoutez de nouvelles valeurs de données à les deux listes 3. appelerplt.gca().lines[0].set_xdata(x); plt.gca().lines[0].set_ydata(y); plt.gca().relim(); plt.gca().autoscale_view(); plt.pause(0.05);
Si vous êtes intéressé par le traçage en temps réel, je vous recommande de consulter l'API d'animation de matplotlib . En particulier, l'utilisation
blit
pour éviter de redessiner l'arrière-plan sur chaque image peut vous donner des gains de vitesse importants (~ 10x):Production:
la source
plt.show()
etplt.draw()
. J'ai ajouté ces modifications au code ci-dessus.blit()
semble - t-elle vraiment "améliorer le traçage en temps réel"? Si vous avez un développeur / blog matplotlib discutant du pourquoi / du but / de l'intention / de la motivation, ce serait formidable. (il semble que cette nouvelle opération de conversion convertirait Matplotlib uniquement en utilisation hors ligne ou en modifiant très lentement les données pour maintenant vous pouvez utiliser Matplotlib avec des données de mise à jour très rapides ... presque comme un oscilloscope).Je sais que je suis un peu en retard pour répondre à cette question. Néanmoins, j'ai créé du code il y a un certain temps pour tracer des graphiques en direct, que je voudrais partager:
Code pour PyQt4:
J'ai récemment réécrit le code de PyQt5.
Code pour PyQt5:
Essayez-le. Copiez-collez ce code dans un nouveau fichier python et exécutez-le. Vous devriez obtenir un beau graphique en mouvement fluide:
la source
dataSendLoop
fil continuait de fonctionner en arrière-plan lorsque vous fermez la fenêtre. J'ai donc ajouté ledaemon = True
mot clé pour résoudre ce problème.conda install pyqt=4
fait l'affaire.show
n'est probablement pas le meilleur choix pour cela. Ce que je ferais, c'est utiliser à lapyplot.draw()
place. Vous pouvez également vouloir inclure un petit délai (par exemple,time.sleep(0.05)
) dans la boucle afin que vous puissiez voir les tracés se produire. Si j'apporte ces modifications à votre exemple, cela fonctionne pour moi et je vois chaque point apparaître un à la fois.la source
Aucune des méthodes n'a fonctionné pour moi. Mais j'ai trouvé que ce tracé matplotlib en temps réel ne fonctionne pas alors qu'il est encore en boucle
Il vous suffit d'ajouter
et ensuite vous pouviez voir les nouvelles parcelles.
Donc, votre code devrait ressembler à ceci, et cela fonctionnera
la source
Les meilleures réponses (et bien d'autres) ont été construites
plt.pause()
, mais c'était une ancienne façon d'animer l'intrigue dans matplotlib. Il est non seulement lent, mais provoque également une concentration sur chaque mise à jour (j'ai eu du mal à arrêter le processus de traçage de python).TL; DR: vous pouvez utiliser
matplotlib.animation
( comme mentionné dans la documentation ).Après avoir creusé autour de diverses réponses et morceaux de code, cela s'est en fait avéré être un moyen fluide de dessiner les données entrantes à l'infini pour moi.
Voici mon code pour un démarrage rapide. Il trace l'heure actuelle avec un nombre aléatoire en [0, 100) toutes les 200 ms à l'infini, tout en gérant la mise à l'échelle automatique de la vue:
Vous pouvez également explorer
blit
pour des performances encore meilleures comme dans la documentation FuncAnimation .Un exemple tiré de la
blit
documentation:la source
for i in range(1000): x,y = some func_func()
. Icisome_func()
génèrex,y
des paires de données en ligne , que je voudrais tracer une fois qu'elles sont disponibles. Est-il possible de le faire avecFuncAnimation
. Mon objectif est de construire la courbe définie par les données étape par étape à chaque itération.pyploy.show()
devrait bloquer. Si vous souhaitez ajouter des données, récupérez-les et mettez à jour laupdate
fonction.pyplot.show
dans une boucle, la boucle sera bloquée par cet appel et ne continuera pas. Si vous souhaitez ajouter des données à la courbe étape par étape, insérez votre logiqueupdate
, qui sera appelée chaqueinterval
donc c'est également étape par étape.Je sais que cette question est ancienne, mais il y a maintenant un paquet disponible appelé drawow sur GitHub comme "python-drawnow". Cela fournit une interface similaire au dessin de MATLAB - vous pouvez facilement mettre à jour une figure.
Un exemple pour votre cas d'utilisation:
python-drawnow est un wrapper mince,
plt.draw
mais offre la possibilité de confirmer (ou déboguer) après l'affichage de la figure.la source
Le problème semble être que vous vous attendez
plt.show()
à afficher la fenêtre, puis à revenir. Ça ne fait pas ça. Le programme s'arrêtera à ce point et ne reprendra qu'une fois que vous aurez fermé la fenêtre. Vous devriez pouvoir tester cela: si vous fermez la fenêtre, puis une autre fenêtre devrait apparaître.Pour résoudre ce problème, appelez simplement
plt.show()
une fois après votre boucle. Ensuite, vous obtenez l'intrigue complète. (Mais pas un «tracé en temps réel»)Vous pouvez essayer de définir l'argument mot-clé
block
comme ceci:plt.show(block=False)
une fois au début, puis utilisez.draw()
pour mettre à jour.la source
Voici une version que j'ai pu travailler sur mon système.
La ligne drawow (makeFig) peut être remplacée par un makeFig (); plt.draw () séquence et cela fonctionne toujours OK.
la source
Si vous voulez dessiner et ne pas geler votre thread car plus de points sont dessinés, vous devez utiliser plt.pause () et non time.sleep ()
im en utilisant le code suivant pour tracer une série de coordonnées xy.
la source
Une autre option consiste à opter pour le bokeh . OMI, c'est une bonne alternative au moins pour les tracés en temps réel. Voici une version bokeh du code dans la question:
et pour l'exécuter:
bokeh affiche le résultat dans un navigateur Web via les communications Websocket. Il est particulièrement utile lorsque les données sont générées par des processus de serveur sans tête distants.
la source
Un exemple d'utilisation pour tracer l'utilisation du processeur en temps réel.
la source