2016-06-03 19 views
2

Immer wenn eine neue TXT-Datei zu einem Verzeichnis hinzugefügt wird, möchte ich die Daten aus der Datei plotten und anzeigen. Wenn eine andere Datei angezeigt wird, möchte ich das Diagramm aktualisieren und die neuen Daten anzeigen. Das Erstellen eines Plots außerhalb des Hauptthreads verursachte Fehler, also habe ich einen (nicht sehr guten) Fix mit globalen Variablen gemacht.Diagramm mit Watchdog dynamisch aktualisieren

Das Problem ist, dass eine weiße Figur erscheint und die Plots nicht angezeigt werden. Nach dem Beenden des Programms verschwindet die weiße Figur und das Diagramm erscheint. Das richtige Bild wird in der Datei gespeichert, aber ich möchte, dass das Bild in Echtzeit angezeigt wird. Wenn ich die plt.show() auskommentiere, erscheinen keine Plots.

Ich versuchte die "Dynamische Aktualisierung Plot in Matplotlib" Antwort (Dynamically updating plot in matplotlib), aber festgestellt, dass, weil es nie aufgerufen, Show(), kein Fenster erschien. Wenn ich versucht habe, show() aufzurufen, blockierte es Updates.

Einfügen plt.pause() hat nicht funktioniert (Real time matplotlib plot is not working while still in a loop)

Das Codebeispiel nicht funktioniert (How to update a plot in matplotlib?)

ist hier mein Code:

import time 
from watchdog.observers import Observer 
from watchdog.events import PatternMatchingEventHandler 
import matplotlib.pyplot as plt 
import numpy as np 
import config 

class MyHandler(PatternMatchingEventHandler): 
    patterns=["*.txt", "*.TXT"] 

    def on_created(self, event): 
     self.process(event) 

    def process(self, event): 
     filename = event.src_path 
     if '_AIt' in filename: 
      config.isnew=True 
      config.fname=filename 


if __name__ == '__main__': 
    observer = Observer() 
    observer.schedule(MyHandler(), path='.', recursive=True) 
    observer.start() 

    dat=[0,1] 
    fig = plt.figure() 
    ax = fig.add_subplot(111) 
    Ln, = ax.plot(dat) 
    ax.set_xlim([0,10]) 
    ax.set_ylim([-1,1]) 
    plt.ion() 
    plt.show()  

    try: 
     while True: 
      time.sleep(1) 
      if config.isnew: 
       config.isnew=False 

       dataarray = np.array(np.transpose(np.loadtxt(config.fname))) 
       dat = dataarray[15] #AI0 
       Ln.set_ydata(dat) 
       Ln.set_xdata(range(len(dat))) 
       plt.savefig(config.fname[:-4] + '.png', bbox_inches='tight') 
       plt.draw() 

    except KeyboardInterrupt: 
     observer.stop() 
    observer.join() 

config.py (erstellt Standardwerte der Konfigurationseinstellung)

isnew=False 
fname="" 

Ich bin verwirrt, weil der folgende Beispiel-Code funktioniert gut (von pylab.ion() in python 2, matplotlib 1.1.1 and updating of the plot while the program runs)

import pylab 
import time 
import matplotlib.pyplot as plt 
import numpy as np 

dat=[0,1] 
fig = plt.figure() 
ax = fig.add_subplot(111) 
Ln, = ax.plot(dat) 
ax.set_xlim([0,20]) 
ax.set_ylim([0,40]) 
plt.ion() 
plt.show()  

for i in range (18): 
    dat=np.array(range(20))+i 
    Ln.set_ydata(dat) 
    Ln.set_xdata(range(len(dat))) 
    plt.pause(1) 

print 'done with loop' 

Antwort

0

Folgendes sollte das tun, was Sie wollen:

import time 
from watchdog.observers import Observer 
from watchdog.events import PatternMatchingEventHandler 
import matplotlib.pyplot as plt 

plt.ion() # enter interactive mode 
ax = fig.add_subplot(111) 
Ln, = ax.plot(dat) 
ax.set_xlim([0,10]) 
ax.set_ylim([-1,1]) 
plt.draw() # non-blocking drawing 
plt.pause(.001) # This line is essential, without it the plot won't be shown 

try: 
    while True: 
     time.sleep(1) 
     if config.isnew: 
      ... 
      plt.draw() 
      plt.pause(.001) 

except KeyboardInterrupt: 
    observer.stop() 
observer.join() 

Die wesentliche dünn ist plt.pause nach dem plt.draw Anruf zu nennen, sonst es wird nicht gezeichnet, wie der andere Python-Codeblock matplotlib. Der Wert .001 ist einfach ein Versuch. Ich weiß nicht wirklich, wie es unter der Haube funktioniert, aber das scheint zu funktionieren.