我正在尝试监视目录中某种类型的新文件, 并在创建它们时对其进行绘制,以在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图。我认为这可能是与线程相关的问题,但是我不确定该如何解决。