J'ai joué avec Numpy et matplotlib ces derniers jours. J'ai des problèmes en essayant de faire de matplotlib plot une fonction sans bloquer l'exécution. Je sais qu'il y a déjà beaucoup de fils ici sur SO posant des questions similaires, et j'ai beaucoup cherché sur Google mais je n'ai pas réussi à faire fonctionner cela.
J'ai essayé d'utiliser show (block = False) comme certains le suggèrent, mais tout ce que j'obtiens est une fenêtre figée. Si j'appelle simplement show (), le résultat est tracé correctement mais l'exécution est bloquée jusqu'à ce que la fenêtre soit fermée. À partir d 'autres threads que j'ai lus, je soupçonne que si show (block = False) fonctionne ou non dépend du backend. Est-ce correct? Mon back-end est Qt4Agg. Pourriez-vous jeter un œil à mon code et me dire si quelque chose ne va pas? Voici mon code. Merci pour toute aide.
from math import *
from matplotlib import pyplot as plt
print plt.get_backend()
def main():
x = range(-50, 51, 1)
for pow in range(1,5): # plot x^1, x^2, ..., x^4
y = [Xi**pow for Xi in x]
print y
plt.plot(x, y)
plt.draw()
#plt.show() #this plots correctly, but blocks execution.
plt.show(block=False) #this creates an empty frozen window.
_ = raw_input("Press [enter] to continue.")
if __name__ == '__main__':
main()
PS. J'ai oublié de dire que je voudrais mettre à jour la fenêtre existante chaque fois que je trace quelque chose, au lieu d'en créer une nouvelle.
la source
plt.ion()
avantplt.show()
? Il doit alors être non bloquant car chaque tracé est généré dans un thread enfant.matplotlib
.Réponses:
J'ai passé un long moment à chercher des solutions et j'ai trouvé cette réponse .
Il semble que, pour obtenir ce que vous (et moi) voulons, vous avez besoin de la combinaison de
plt.ion()
,plt.show()
(pas avecblock=False
) et, surtout,plt.pause(.001)
(ou à tout moment que vous voulez). La pause est nécessaire car les événements GUI se produisent pendant que le code principal est en veille, y compris le dessin. Il est possible que cela soit implémenté en récupérant le temps d'un thread endormi, alors peut-être que les IDE gâchent cela - je ne sais pas.Voici une implémentation qui fonctionne pour moi sur python 3.5:
la source
plt.draw
suiviplt.show(block = False)
mais cela a cessé de fonctionner: la figure ne répond pas, la fermeture a planté iPython. Ma solution consistait à supprimer chaque instance deplt.draw()
et à la remplacer parplt.pause(0.001)
. Au lieu de l'avoir suivi deplt.show(block = False)
commeplt.draw
avant, il était précédé deplt.ion()
etplt.show()
. J'en ai maintenant unMatplotlibDeprecationWarning
mais cela m'a permis de tracer mes chiffres, donc je suis content de cette solution.raw_input
notinput
. Voir iciUne astuce simple qui fonctionne pour moi est la suivante:
Exemple :
Remarque :
plt.show()
est la dernière ligne de mon script.la source
Vous pouvez éviter de bloquer l'exécution en écrivant le tracé dans un tableau, puis en affichant le tableau dans un thread différent. Voici un exemple de génération et d'affichage simultanés de tracés à l'aide de pf.screen de pyformulas 0.2.8 :
Résultat:
Clause de non-responsabilité: je suis le mainteneur de pyformulas.
Référence: Matplotlib: enregistrer le tracé dans le tableau numpy
la source
Beaucoup de ces réponses sont super gonflées et d'après ce que je peux trouver, la réponse n'est pas si difficile à comprendre.
Vous pouvez utiliser
plt.ion()
si vous le souhaitez, mais j'ai trouvé l'utilisationplt.draw()
tout aussi efficacePour mon projet spécifique, je trace des images, mais vous pouvez utiliser
plot()
ouscatter()
ou quoi que ce soit à la place defigimage()
, cela n'a pas d'importance.Ou
Si vous utilisez un chiffre réel.
J'ai utilisé les réponses de @ krs013 et de @Default Picture
pour comprendre cela.
la source
Tracé en direct
si la quantité de données est trop importante, vous pouvez réduire le taux de mise à jour avec un simple compteur
Maintenir le tracé après la sortie du programme
C'était mon problème réel pour lequel je ne trouvais pas de réponse satisfaisante, je voulais un tracé qui ne se fermait pas une fois le script terminé (comme MATLAB),
Si vous y réfléchissez, une fois le script terminé, le programme se termine et il n'y a pas de moyen logique de tenir le tracé de cette façon, il y a donc deux options
ce n'était pas satisfaisant pour moi alors j'ai trouvé une autre solution en dehors de la boîte
SaveToFile et View dans un visualiseur externe
Pour cela, l'enregistrement et la visualisation doivent être à la fois rapides et le spectateur ne doit pas verrouiller le fichier et doit mettre à jour le contenu automatiquement
Sélection du format pour l'enregistrement
les formats vectoriels sont à la fois petits et rapides
Visionneuse rapide et légère avec mise à jour en direct
Pour PDF, il existe plusieurs bonnes options
Sous Windows, j'utilise SumatraPDF qui est gratuit, rapide et léger (n'utilise que 1,8 Mo de RAM pour mon cas)
Sous Linux, il existe plusieurs options telles que Evince (GNOME) et Ocular (KDE)
Exemple de code et résultats
Exemple de code pour la sortie du tracé dans un fichier
après la première exécution, ouvrez le fichier de sortie dans l'un des visualiseurs mentionnés ci-dessus et profitez-en.
Voici une capture d'écran de VSCode aux côtés de SumatraPDF, également le processus est assez rapide pour obtenir un taux de mise à jour semi-live (je peux me rapprocher de 10Hz sur ma configuration juste utiliser
time.sleep()
entre les intervalles)la source
La réponse d'Iggy a été la plus simple à suivre pour moi, mais j'ai eu l'erreur suivante en exécutant une
subplot
commande ultérieure qui n'était pas là lorsque je faisais justeshow
:Afin d'éviter cette erreur, il est utile de fermer (ou d' effacer ) le tracé une fois que l'utilisateur a cliqué sur Entrée.
Voici le code qui a fonctionné pour moi:
la source
Le package Python drawnow permet de mettre à jour un tracé en temps réel de manière non bloquante.
Il fonctionne également avec une webcam et OpenCV par exemple pour tracer des mesures pour chaque image.
Voir l'article original .
la source