Seite 1 von 1

wie pylab-plot in echtzeit aktualisieren?

Verfasst: Mittwoch 29. Februar 2012, 14:02
von dall♀
nach meinem letzten, leider unbeantworteten post bin ich etwas weiter vorangekommen und die probleme sitzen woanders, vielleicht kann mir ja jetzt jemand helfen.

jetzt erstmal die vorgeschichte, dann meine fragen.

von meinem hauptprogramm aus erstelle ich ein neues objekt meiner eigenen klasse Plotting, die von threading.Thread erbt. der thread wird dann vom hauptprogramm aus gestartet, das natürlich parallel weiterläuft:

Code: Alles auswählen

plot = Plotting(tmpFilePath, unit, scanKeys, plotKeys)
plot.start()
einfaches plotten ohne zeitliche aktualisierung funktioniert ohne probleme und zwar sinngemäß so:

Code: Alles auswählen

def run(self):

        # (...)

        pylab.ion()                    # interactive mode on
        fig = pylab.figure(id)      # figure erstellen
        
        # daten für die plots aus datei holen usw., werden dann gespeichert im dictionary self.__data/self.__timestamps
        self.__initPlots()
        
        # zeichnen
        for key in self.__plotKeys:
            line, = pylab.plot(self.__timestamps, self.__data[key], label=Globals.CONFIGFILE.Channels[key].Name)
            self.__lines[key] = line
        
        pylab.draw()
dann wird die figure angezeigt und nach dem schließen läuft das hauptprogramm normal weiter.

ABER:

für den fall, dass der benutzer einen plot sehen will, der sich kontinuierlich aktualisiert, geht es mit einer schleife weiter:

Code: Alles auswählen

while True:
                self.__getData()                               # neue daten holen und self.__data/self.__timestamps aktualisieren
   
                ''' # methode 1
                for key in self.__plotKeys:
                    self.__lines[key].set_xdata(self.__timestamps)
                    self.__lines[key].set_ydata(self.__data[key])
                '''
                # methode 2
                for key in self.__plotKeys:
                    del self.__lines[key]
                    line, = pylab.plot(self.__timestamps, self.__data[key], label=Globals.CONFIGFILE.Channels[key].Name)
                    self.__lines[key] = line
                
                pylab.draw()
meine probleme:

- methode 1 funktioniert überhaupt nicht, das programm friert ohne fehlermeldung ein. warum?
- methode 2 aktualisiert die linien fortlaufend, aber sie wechseln immer die farbe, als würden immer neue plots hinzugefügt werden (daher der versuch des löschens mit del self.__lines[key] - scheint aber nichts zu bringen)
- wie kann ich den klick auf das X des plot-fensters abfangen, um die schleife zu beenden? sonst läuft der thread ja bis in alle ewigkeit weiter.
- warum bringt der erste klick auf den plot-button im hauptprogramm immer keinen plot hervor, obwohl der thread gestartet wurde (danach geht es aber, also mit dem zweiten klick)? habe dazu auch versucht, unterschiedliche backends zu benutzen (matplotlib.use('GTK'), matplotlib.use('GtkAgg'), matplotlib.use('TkAgg')), aber alles funktioniert.. naja, unterschiedlich schlecht. wer dazu mehr wissen will, dem kann ich auch noch fehlermeldungen präsentieren.

hat jemand auch nur einen klitzekleinen tipp zu irgendeinem problem davon für mich? hab ich irgendwas übersehen?

Re: wie pylab-plot in echtzeit aktualisieren?

Verfasst: Mittwoch 7. März 2012, 07:22
von Leonidas
Einer der klitzekleinen Tipps ist: GUI-Toolkits und Threads = keine gute Idee, da sie nicht threadsicher sind. Daher sind die Updates immer von dem Thread auszuführen, in dem man die GUI laufen lässt. Und meist, bei kurzen Interaktionen ist es nicht notwendig Threads zu verwenden, da kann man üblicherweise via ``idle_add`` oder ``timeout_add`` Code ausführen lassen.

Re: wie pylab-plot in echtzeit aktualisieren?

Verfasst: Freitag 9. März 2012, 11:40
von dall♀
hallo leonidas,
danke für deinen tipp. hab den plot jetzt als eigenes programm angelegt und übergebe ihm das datafile per kommandozeile. jetzt funktioniert alles anstandslos. ein bisschen entsetzt bin ich schon, wie viel probleme das machen kann ;)