web-dev-qa-db-fra.com

matplotlib: génère un nouveau graphique dans une nouvelle fenêtre pour les exécutions ultérieures du programme

J'ai un programme Python qui génère des graphiques en utilisant matplotlib. J'essaie de faire en sorte que le programme génère un ensemble de tracés dans une exécution de programme (l'utilisateur est invité à indiquer s'il souhaite générer un autre graphique), le tout dans des fenêtres séparées. Je peux faire ça?

3
Syd

Pour générer une nouvelle figure, vous pouvez ajouter plt.figure () avant tout tracé effectué par votre programme.

import matplotlib.pyplot as plt
import numpy as np

def make_plot(slope):
    x = np.arange(1,10)
    y = slope*x+3
    plt.figure()
    plt.plot(x,y)

make_plot(2)
make_plot(3)
4
Zach Fox

Le moyen le plus simple de vous assurer que toutes vos lignes sont dirigées vers la fenêtre de chiffre correcte est le suivant:

from six.moves import input
import matplotlib.pyplot as plt
another = True
while another:
    fig, ax = plt.subplots()

    ax.plot(range(5))


    fig.canvas.manager.show() 
    # this makes sure that the gui window gets shown
    # if this is needed depends on rcparams, this is just to be safe
    fig.canvas.flush_events() 
    # this make sure that if the event loop integration is not 
    # set up by the gui framework the plot will update

    another = bool(input("would you like another? "))

Si vous voulez exécuter ceci avec un back-end non-gui, vous devrez abandonner l'appel flush_events ou l'envelopper dans un try: ... except NotImplementedError. Une grande partie de cette complication est liée à la programmation défensive, car les interfaces utilisateur graphiques peuvent être difficiles et le comportement de ce code peut dépendre de nombreux facteurs qui ne ressortent pas du code affiché.

L'utilisation des axes implicites de pyplot peut poser des problèmes car les "axes actuels" sont définis par les derniers axes sur lesquels l'utilisateur a cliqué. Vous ne devriez vraiment utiliser que pyplot lors de la saisie interactive sur le rpel et presque jamais (autre que plt.subplots) dans les scripts/programmes.

1
tacaswell

En utilisant la dernière version de matlibplot, les éléments suivants ont fonctionné pour mes besoins:

# create figure (will only create new window if needed)
plt.figure()
# Generate plot1
plt.plot(range(10, 20))
# Show the plot in non-blocking mode
plt.show(block=False)

# create figure (will only create new window if needed)
plt.figure()
# Generate plot2
plt.plot(range(10, 20))
# Show the plot in non-blocking mode
plt.show(block=False)

...

# Finally block main thread until all plots are closed
plt.show()
1
user1495323