2010-08-18 6 views
2

J'essaie de construire une petite interface graphique qui a un tracé qui se met à jour chaque fois qu'un nouvel échantillon de données est lu. Je préférerais ne pas l'utiliser avec une minuterie, car les données arriveront à des intervalles différents. Au lieu de cela, j'essaie de faire une mise en œuvre en utilisant des signaux, où la fonction de collecte de données émettra un signal lorsque les données sont lues, puis la fonction de peinture émettra un signal lorsque la peinture est terminée. Le problème, tel qu'il apparaît en ce moment, est que le canevas ne se met pas à jour dès que j'appelle canvas.draw(). Lorsque ce programme s'exécute, data_collect() et paint() alternent les signaux d'envoi, mais la figure n'est pas mise à jour avant que j'arrête le processus. Comment puis-je forcer matplotlib à mettre à jour la figure quand paint() est appelée?comment forcer matplotlib à mettre à jour une parcelle

Ce qui suit est une pièce relativement simple de code exemple qui n'est pas optimale, mais nous l'espérons, donner la saveur de ce que je suis en train de faire ...

N_length = 150; 
count = [0]; 

def sinval(delay): 

    k = 0; 
    x = []; 

    # set up data vector with sinusoidal data in it. 
    while k < N_length: 
     x.append(math.sin(2*math.pi*k/N_length)); 
     k += 1; 

    def next(): 

     time.sleep(delay); 
     outstring = "%0.3e" % (x[count[0]]); 

     if (count[0] == (N_length-1)): 
      count[0] = 0; 
     else: 
      count[0] += 1; 

     return outstring; 

    return next; 


class DesignerMainWindow(QtGui.QMainWindow, Ui_mplMainWindow): 

    def __init__(self, parent = None): 
     super(DesignerMainWindow, self).__init__(parent) 
     self.setupUi(self) 

     QtCore.QObject.connect(self.mplStartButton, QtCore.SIGNAL("clicked()"), self.start_graph); 
     QtCore.QObject.connect(self.mplStopButton, QtCore.SIGNAL("clicked()"), self.stop_graph); 
     QtCore.QObject.connect(self.mplQuitButton, QtCore.SIGNAL("clicked()"), QtGui.qApp, QtCore.SLOT("quit()")); 
     QtCore.QObject.connect(self, QtCore.SIGNAL("data_collect()"), self.data_collect); 
     QtCore.QObject.connect(self, QtCore.SIGNAL("paint()"), self.paint); 

    def start_graph(self): 

     # generates first "empty" plots 
     self.user = []; 
     self.l_user, = self.mpl.canvas.ax.plot([], self.user, label='sine wave'); 

     # set up the axes. 
     self.mpl.canvas.ax.set_xlim(0, 300); 
     self.mpl.canvas.ax.set_ylim(-1.1, 1.1); 
     self.mpl.canvas.draw(); 

     # start the data collection process. 
     self.delay = 0.05; 
     self.next = sinval(self.delay); 
     self.emit(QtCore.SIGNAL('data_collect()')); 


    def data_collect(self): 
     outstring = self.next(); 
     self.user.append(float(outstring.split()[0])); 
     self.l_user.set_data(range(len(self.user)), self.user); 
     self.emit(QtCore.SIGNAL('paint()')); 


    def paint(self): 
     self.mpl.canvas.draw(); 
     self.emit(QtCore.SIGNAL('data_collect()')); 
+0

Ai-je raté quelque chose, ou avez-vous omis toutes les commandes de traçage? Ni 'data_collect' ni' paint' ne semblent avoir de commandes de type plot (comme 'self.mpl.canvas.ax.plot') qui modifieraient l'intrigue. Donc, ne pas appeler 'self.mpl.canvas.draw()' juste redessiner le même ancien tracé? – unutbu

+0

@ ~ unutbu - Il configure la mise à jour des données de l'intrigue avec 'self.l_user.set_data (...)' plutôt que de tout replacer. (C'est beaucoup plus efficace qu'un appel à tracer, si vous voulez juste changer les données de l'intrigue et ne pas redessiner les graduations de l'axe, etc.) –

+0

je comprenais que la mise à jour de l_user.set_data et l'invocation de canvas.draw() se rafraîchiraient automatiquement la figure. J'ai essayé de changer la première commande en peinture (self) en self.mpl.canvas.ax.plot(), mais cela ne semblait pas faire l'affaire. comment devrais-je changer cette commande? merci - – user424211

Répondre

1

Je suppose que l'appel QCoreApplication :: processEvents après paint() aidera. Plus élégant serait d'avoir un QThread séparé pour la lecture. Jetez un oeil à ce thread.

+0

Merci! J'ai dû appeler QtGui.QApplication.processEvents() dans PyQt4, mais cela a fait l'affaire. – user424211

Questions connexes