7
votes

Maplotlib Pyplot Show () ne fonctionne pas une fois fermé

J'ai une boucle comme celle-ci xxx

cela fonctionne bien lorsque je = 0. Pour le programme de continuer, j'ai besoin de fermer la nouvelle figure créée par Pyplot. Pour toutes les autres itérations de boucle (I> 0), une autre nouvelle figure n'est pas créée, une parcelle n'est pas présentée et le programme passe simplement. Pourquoi la fermeture d'une figure faisant un pyplot incapable d'ouvrir une nouvelle (comme Matlab)?

Le comportement que j'attends est le suivant:

  1. L'exécution s'arrête à p.show ()
  2. Quand je ferme la figure, l'exécution continue
  3. Lorsque p.show () est retrouvé à nouveau, la nouvelle image est affichée.
  4. Répétez l'étape 2 jusqu'à ce que plus de complot soit montrant

2 commentaires

Je suis capable de créer des parcelles séquentielles pour N> = 2. À quelle e-IDE utilisez-vous (si vous utilisez un)? Je dois fermer manuellement l'intrigue avant que je reçoive le prochain, donc dans cet exemple p.close () est inutile.


J'utilise Pycham pour écrire le script et l'exécuter. Je remarque que ce problème semble se produire uniquement lorsqu'il fonctionne comme un script au lieu de ipython -pylab


5 Réponses :


5
votes

Il pourrait y avoir une meilleure façon d'animer Imshow, mais cela devrait travailler dans une pincée. C'est une version légèrement modifiée d'un exemple d'animation des docs .

# For detailed comments on animation and the techniqes used here, see
# the wiki entry http://www.scipy.org/Cookbook/Matplotlib/Animations

import matplotlib
matplotlib.use('TkAgg')

import matplotlib.pyplot as plt
import matplotlib.mlab as mlab
import matplotlib.cm as cm

import sys
import numpy as np
import time

ax = plt.subplot(111)
canvas = ax.figure.canvas

delta=0.025
x=y= np.arange(-3.0, 3.0, delta)
x,y=np.meshgrid(x, y)
z1=mlab.bivariate_normal(x, y, 1.0, 1.0, 0.0, 0.0)
z2=mlab.bivariate_normal(x, y, 1.5, 0.5, 1, 1)
z=z2-z1  # difference of Gaussians

def run(z):
    fig=plt.gcf()
    for i in range(10):
        plt.imshow(z, interpolation='bilinear', cmap=cm.gray,
                  origin='lower', extent=[-3,3,-3,3])
        canvas.draw()
        plt.clf()
        z**=2

manager = plt.get_current_fig_manager()
manager.window.after(100, run, z)
plt.show()


4 commentaires

Votre solution est idéale pour l'animation. Mais ce que je veux, ce n'est pas l'animation, je veux juste un comportement simple de type matlab où je peux visualiser une certaine image / matrice lorsque mon algorithme fonctionne.


@DAT CHU: Je ne connais pas le comportement de Matlab.


@DAT CHU: Avez-vous besoin de faire une pause d'exécution du code pendant l'affichage de la parcelle?


@DAT CHU: Vous pourrez peut-être obtenir votre script à exécuter (comme intérieur ipython -pylab ) en ajoutant p.ion () . Cela met Matplotlib en mode interactif. Chaque commande MATPLOTLIB est affichée immédiatement. Cela pourrait être correct pour le débogage, mais je pense qu'il est mal vu de scripts «sérieux». Pour de telles situations, je pense que vous êtes encouragé à utiliser un gestionnaire de figure, comme indiqué ci-dessus.



3
votes

Cela pourrait provenir d'un bogue dans les versions précédentes de Matplotlib. J'avais un problème similaire lorsque j'ai émis des commandes séquentielles show () - Seul le premier montrerait (et resterait); Mais quand j'ai mis à jour Matplotlib à 1.0.1, le problème est parti.


2 commentaires

J'ai mis à jour à Matplotlib Svn et le problème disparaît. Je suppose que c'est un bug.


C'était "Quoi de neuf" pour la version 1.0.1: Une demande longue consiste à prendre en charge plusieurs appels à montrer (). Cela a été difficile, car il est difficile d'obtenir un comportement cohérent entre les systèmes d'exploitation, les boîtes à outils d'interface utilisateur et les versions. Eric Cocking a fait beaucoup de travail sur la rationalisation du spectacle à travers les backends, avec le comportement souhaité de faire des spectacles augmenter toutes les figures nouvellement créées et une exécution de blocs jusqu'à ce qu'ils soient fermés. Les appels répétés à montrer doivent soulever des chiffres nouvellement créés depuis le dernier appel ...



0
votes

Après avoir timing avec l'exemple de tsutbu, j'ai trouvé un comportement que je pouvais normalement et déboguer avec Pydev où je pouvais voir progressivement les parcelles.

import time, threading
import numpy
from matplotlib.pyplot import *

x = numpy.linspace(0, 10)
y = x**2

def main():
    plot(x, x)
    draw()
    time.sleep(2)
    plot(x, y)
    draw()

thread = threading.Thread()
thread.run = main

manager = get_current_fig_manager()
manager.window.after(100, thread.start)
figure(1)
show()


1 commentaires

Notez que si vous avez plusieurs chiffres, je vous suggérerais que vous les «préalez-vous» avant de montrer () la figure Windows. Sinon, toute nouvelle figure semble être confinée au fil d'appel.



0
votes

J'ai longtemps examiné ce problème et j'ai peut-être une solution bien que je ne l'ai pas encore testé complètement.

La clé consiste à écrire plus de code comme MATLAB, nommez vos chiffres, puis appelez-les à Afficher () code>. p>

EG. P>

 from matplotlib import pyplot as plt

 fig1 = plt.figure()
 fig2 = plt.figure()

 fig1.show()
 fig2.show()


0 commentaires

0
votes

SEULEMENT SET

import matplotlib
matplotlib.use('Agg')


0 commentaires