如何动态绘制数据以响应看门狗事件

时间:2018-12-31 13:41:51

标签: python matplotlib thread-safety watchdog python-watchdog

我正在尝试监视目录中某种类型的新文件, 并在创建它们时对其进行绘制,以在python中生成实时动画。

为此,我正在使用看门狗包来监视文件系统中的更改,并且创建了一个自定义处理程序类来初始化绘图,并在创建正确类型的新文件时更新绘图。

"""
Created on Mon Dec 31 11:11:33 2018
For plotting real time open-ifs output

"""
#general modules
import numpy as np
import os
import sys
import time
#monitoring modules
from watchdog.observers import Observer
from watchdog.events import PatternMatchingEventHandler
#data load modules
from iris import load_cube, Constraint
import warnings
warnings.simplefilter('ignore')
#plotting modules
import iris.plot as iplt
import matplotlib.pyplot as plt
import cartopy.crs as ccrs



#A custom handler class inherited from PatternMatchingEventHandler
#This will check new files and if of the correct type, plot them.
class PlottingHandler(PatternMatchingEventHandler):

    def setup_handler(self,load_function,title_function,format_specifier):
        #Must take in only a filename, and return only a datacube
        self.load_func=load_function
        #Must take in only a filename and return only a title
        self.title_func=title_function
        #Must take in only a filename and return a boolean value
        self.format_specifier=format_specifier

    #these methods setup and update the plot
    def setup_plot(self,cmap,proj):
        self.cmap=cmap
        self.proj=proj
        self.fig , _ =plt.subplots(1,1,figsize=(10,10))
        self.ax = plt.axes(projection=proj)
        plt.tight_layout()
        plt.show()

    def update_plot(self,file):
        self.ax.cla()
        cube=self.load_func(file)
        iplt.contourf(cube, 30, cmap=self.cmap,fig=self.fig)
        self.ax.coastlines(color='white')
        plt.clim([224.0, 273.0])
        self.fig.suptitle(self.title_func(file))
        self.fig.canvas.draw()
        self.fig.canvas.flush_events()
        plt.pause(0.1)

    #these methods execute in response to file changes:
    def on_created(self,event):
        #if the filename is of the correct type then we will plot the new file
        if self.format_specifier(event.src_path) ==True:
            print("plotting new file")
            self.update_plot(event.src_path)
        else:
            print("new file not of plottable type")



#RELEVANT FUNCTIONS:
#Loads data from file
def LoadTempCube(file):
    temp=load_cube(file, 'Temperature').extract(Constraint(air_pressure=50000.0))
    temp = temp.extract(Constraint(time=lambda cell: True))
    return temp
#Creates title of plot from file 
def SimpleTitle(file):
    title=file.rsplit('/',1)[-1]
    return title
#determines if file is one we want to plot
def is_NetCDFfile(file):
    file=file.rsplit('/',1)[-1]
    ExpID="ICMSHh3a5"
    conditions=[]
    conditions.append(file.startswith(ExpID))
    conditions.append(file.endswith(".nc"))
    return np.all(conditions)

#PARAMETERS:          
path="/network/aopp/chaos/pred/dorrington/raspberry_pis/dummy/"  
color_map = plt.get_cmap('inferno')
proj = ccrs.Mollweide()

#EXECUTABLE CODE:
if not os.path.isdir(path):
    print("invalid file path")
    sys.exit(0)

#enable interactive plotting:
plt.ion()
#the handler responds to events detected by the observer
handler=PlottingHandler()

#We pass the relevant functions to the handler...
handler.setup_handler(LoadTempCube,SimpleTitle,is_NetCDFfile)

#... and setup the plot
handler.setup_plot(color_map,proj)
plt.pause(0.1)
#We initialise the observer object, which monitors the folder for file changes   
observer=Observer()
#we tell the observer who to pass events to, and where to look for them...
observer.schedule(handler,path)

#...and we begin monitoring
print("start")
observer.start()
observer.join()

这在Spyder中以交互方式运行时如我所愿,但是当尝试从终端运行时,代码只是结束了。我必须添加observer.join()行来防止这种情况,但是现在观察器不允许更新matplotlib图。我认为这可能是与线程相关的问题,但是我不确定该如何解决。

0 个答案:

没有答案