class PlotFrame: def __init__(self, parent): self.parent = parent # TOP FRAME - CANVAS self.f = plt.figure(figsize=(5, 5)) self.a = self.f.add_subplot(111) self.a.grid(True) #self.a.set_xlabel(self.description) self.a.set_ylabel("Probability") self.canvas = FigureCanvasTkAgg(self.f, master=parent) self.canvas.get_tk_widget().pack(side=TOP, fill=BOTH, expand=1) self.canvas._tkcanvas.pack(side='top', fill='both', expand=1) def update(self): self.canvas.draw() def get_plot(self): return self.a def plot(self, ext): from tkFileDialog import asksaveasfilename name = 'puq-plot' filename = asksaveasfilename(title="Plot to file...", initialfile=name, defaultextension='.%s' % ext, filetypes=[(ext.upper(), '*.%s' % ext)]) if not filename: return self.canvas.print_figure(filename)
class PlotFrame: def __init__(self, parent): self.parent = parent # TOP FRAME - CANVAS self.f = plt.figure(figsize=(5, 5)) self.a = self.f.add_subplot(111) self.a.grid(True) #self.a.set_xlabel(self.description) self.a.set_ylabel("Probability") self.canvas = FigureCanvasTkAgg(self.f, master=parent) self.canvas.get_tk_widget().pack(side=TOP, fill=BOTH, expand=1) self.canvas._tkcanvas.pack(side='top', fill='both', expand=1) def update(self): self.canvas.draw() def get_plot(self): return self.a def plot(self, ext): name = 'puq-plot' filename = asksaveasfilename(title="Plot to file...", initialfile=name, defaultextension='.%s' % ext, filetypes=[(ext.upper(), '*.%s' % ext)]) if not filename: return self.canvas.print_figure(filename)
class twodplot(Tk.Frame): def __init__(self, parent=None, data=None, quiet="No"): Tk.Frame.__init__(self, parent) self.quiet = quiet self.f = Figure(figsize=(8, 5), dpi=100) self.a = self.f.add_subplot(111) self.plotitems = {} self.maxpoints = 1000000 # work around slow plotting # print data if data is not None: self.plotitems[data[0]] = data[1] self.title = None self.xr = self.yr = None # a tk.DrawingArea self.canvas = FigureCanvasTkAgg(self.f, master=self) self.canvas.draw() self.tkc = self.canvas.get_tk_widget() self.tkc.pack(side=Tk.TOP, fill=Tk.BOTH, expand=1) self.tkc.bind("<ButtonPress-1>", self.on_down) self.tkc.bind("<ButtonRelease-1>", self.on_up) self.tkc.bind("<Button1-Motion>", self.on_move) self.tkc.bind("<ButtonPress-2>", self.on_2) self.tkc.bind("<ButtonPress-3>", self.on_3) self.when_down = -1 self.time_down = 0.1 self.bindkeys() self.rubberbandbox = None self.pack_opts = {'side': Tk.LEFT, 'padx': '2', 'pady': '2'} self.bf1 = Tk.Frame(self) Tk.Button(master=self.bf1, text='Clear', command=self.clear).pack(self.pack_opts) Tk.Button(master=self.bf1, text='Save Plot', command=self.printplot).pack(self.pack_opts) Tk.Button(master=self.bf1, text='LogY', command=self.logy).pack(self.pack_opts) Tk.Button(master=self.bf1, text='LogX', command=self.logx).pack(self.pack_opts) # FIXME - buttons for panx/y and zoomx/y Tk.Button(master=self.bf1, text='>', command=lambda: self.keypress(self.a.panx, 1)).pack( self.pack_opts) Tk.Button(master=self.bf1, text='<', command=lambda: self.keypress(self.a.panx, -1)).pack( self.pack_opts) Tk.Button(master=self.bf1, text='^', command=lambda: self.keypress(self.a.pany, -1)).pack( self.pack_opts) Tk.Button(master=self.bf1, text='v', command=lambda: self.keypress(self.a.pany, 1)).pack( self.pack_opts) self.bf1.pack(side=Tk.BOTTOM) self.bf2 = Tk.Frame(self) Tk.Button(master=self.bf2, text='UnZoomX', command=lambda: self.keypress(self.a.zoomx, -1)).pack( self.pack_opts) Tk.Button(master=self.bf2, text='ZoomX', command=lambda: self.keypress(self.a.zoomx, 1)).pack( self.pack_opts) Tk.Button(master=self.bf2, text='ZoomY', command=lambda: self.keypress(self.a.zoomy, 1)).pack( self.pack_opts) Tk.Button(master=self.bf2, text='UnZoomY', command=lambda: self.keypress(self.a.zoomy, -1)).pack( self.pack_opts) Tk.Button(master=self.bf2, text='Autoscale', command=lambda: self.keypress(self.autoscale)).pack( self.pack_opts) Tk.Button(master=self.bf2, text='Autoscale Y', command=lambda: self.keypress(self.autoscaley, None)).pack( self.pack_opts) self.bf2.pack(side=Tk.BOTTOM) self.label = Tk.Label(self, text="Plot window messages") self.label.pack(side=Tk.BOTTOM, fill=Tk.X, expand=0) self.pack(side=Tk.TOP, fill=Tk.BOTH, expand=Tk.YES) self.hidden = [] self.replot() self.xd = None self.yd = None def printplot(self): fn = filedialog.asksaveasfilename(title="File name to print to", defaultextension="png") print(fn) f, e = os.path.splitext(fn) extns = ['png', 'ps', 'eps', 'bmp', 'raw', 'rgb'] print(e) if e.lower() in ['.png', '.ps', '.eps', '.bmp', '.raw', '.rgb']: self.update_idletasks() # Try to get screen redrawn self.canvas.print_figure(fn, dpi=300, orientation='landscape') else: messagebox.showinfo( "Sorry", "I can only make output in these formats" + str(extns)) def keypress(self, *arg): if len(arg) > 1: arg[0](*arg[1:]) else: arg[0]() self.canvas.draw() def bindkeys(self): return self.bind_all('<Left>', lambda e: self.keypress(self.a.panx, 1)) self.bind_all('<Right>', lambda e: self.keypress(self.a.panx, -1)) self.bind_all('<Up>', lambda e: self.keypress(self.a.pany, -1)) self.bind_all('<Down>', lambda e: self.keypress(self.a.pany, 1)) self.bind_all('<Shift-Left>', lambda e: self.keypress(self.a.zoomx, -1)) self.bind_all('<Shift-Right>', lambda e: self.keypress(self.a.zoomx, 1)) self.bind_all('<Shift-Up>', lambda e: self.keypress(self.a.zoomy, 1)) self.bind_all('<Shift-Down>', lambda e: self.keypress(self.a.zoomy, -1)) self.bind_all('<Next>', lambda e: self.keypress(self.autoscale)) self.bind_all('<Prior>', lambda e: self.keypress(self.autoscaley, e)) def autoscaley(self, e): print(dir(self.a.dataLim)) print(self.a.dataLim) yr = self.a.get_ylim() self.a.set_ylim(yr) def adddata(self, data): """ Takes a tuple of name, data object """ self.plotitems[data[0]] = data[1] if data[0] in self.hidden: self.hidden.remove(data[0]) self.replot() def hideall(self): self.xr = self.yr = None for item in list(self.plotitems.keys()): self.hidden.append(item) def removedata(self, name): try: self.plotitems.pop(name) except KeyError: pass def replot(self): self.a.clear() if self.title is not None: self.a.set_title(self.title) # b : blue # g : green # r : red # c : cyan # m : magenta # y : yello # c = ['g','r','c','m','y','b'] for name in list(self.plotitems.keys()): if name in self.hidden: continue item = self.plotitems[name] #print 'x ', item.x #print 'y ', item.y #print 'd ', item.d #print self.plotitems[name].d # if item.d.has_key('color'): # pc=item.d['color'] # else: # c.append(c[0]) # pc=c.pop(0) if 'plotopts' in item.d: po = item.d['plotopts'] else: po = {'marker': '.', 'linestyle': 'none', 'alpha': 0.25} if "xlabel" in item.d: self.a.set_xlabel(item.d["xlabel"]) if "ylabel" in item.d: self.a.set_ylabel(item.d["ylabel"]) if "title" in item.d: self.a.set_title(item.d["title"]) try: if "plottype" in item.d: ret = self.a.hist(item.y, item.x) elif item.x.shape[0] > self.maxpoints: if self.quiet == "No": if messagebox.askyesno( "Slow plotting workaround", "Shall I plot only the first %d points for increased speed?" % (self.maxpoints)): ret = self.a.plot(item.x[:self.maxpoints], item.y[:self.maxpoints], **po) else: ret = self.a.plot(item.x, item.y, **po) else: ret = self.a.plot(item.x[:self.maxpoints], item.y[:self.maxpoints], **po) else: ret = self.a.plot(item.x, item.y, **po) except: print("plotting exception ignored") raise if self.xr is not None: self.a.set_xlim(self.xr) if self.yr is not None: self.a.set_ylim(self.yr) self.canvas.draw() def logy(self): # FIXME - clip negative values before making logscaled? if self.a.yaxis.is_log(): self.a.set_yscale('linear') else: self.a.set_yscale('log') self.canvas.draw() def logx(self): # FIXME - clip negative values before making logscaled? if self.a.xaxis.is_log(): self.a.set_xscale('linear') else: self.a.set_xscale('log') self.canvas.draw() def on_3(self, event): self.autoscale() def autoscale(self): self.a.cla() self.xr = self.yr = None self.replot() def clear(self): self.plotitems = {} self.replot() def on_2(self, event): try: height = self.f.bbox.height() x, y = event.x, height - event.y (xd, yd) = self.a.transData.inverse_xy_tup((x, y)) except: height = self.f.bbox.height x, y = event.x, height - event.y (xd, yd) = self.a.transData.inverted().transform((x, y)) self.label.config(text="Clicked at x=%f y=%f" % (xd, yd)) # Callback functions for mouse def on_down(self, event): # get the x and y coords, flip y from top to bottom self.when_down = time.time() try: height = self.f.bbox.height() x, y = event.x, height - event.y (self.xd, self.yd) = self.a.transData.inverse_xy_tup((x, y)) except: height = self.f.bbox.height x, y = event.x, height - event.y (self.xd, self.yd) = self.a.transData.inverted().transform((x, y)) # transData transforms data coords to display coords. Use the # inverse method to transform back # print "print mouse down at", t, val # rubber banding: if self.rubberbandbox is not None: self.tkc.delete(self.rubberbandbox) self.startx = self.tkc.canvasx(event.x) self.starty = self.tkc.canvasx(event.y) def on_move(self, event): x = self.tkc.canvasx(event.x) y = self.tkc.canvasy(event.y) if (self.startx != event.x) and (self.starty != event.y): if self.rubberbandbox is not None: self.tkc.delete(self.rubberbandbox) self.rubberbandbox = self.tkc.create_rectangle(self.startx, self.starty, x, y, outline='green') # this flushes the output, making sure that # the rectangle makes it to the screen # before the next event is handled def on_up(self, event): # get the x and y coords, flip y from top to bottom if self.xd == None: return if time.time() - self.when_down < self.time_down and self.when_down > 0: return self.tkc.delete(self.rubberbandbox) try: height = self.f.bbox.height() x, y = event.x, height - event.y (self.xu, self.yu) = self.a.transData.inverse_xy_tup((x, y)) except: height = self.f.bbox.height x, y = event.x, height - event.y (self.xu, self.yu) = self.a.transData.inverted().transform((x, y)) # transData transforms data coords to display coords. Use the # inverse method to transform back if self.xu != self.xd and self.yu != self.yd: # rescale xr = [self.xd, self.xu] xr.sort() yr = [self.yd, self.yu] yr.sort() self.xr = xr self.yr = yr self.a.set_xlim(xr) self.a.set_ylim(yr) self.canvas.draw()
def drawBatch(fig,filename): canvas=CanvasBackend(fig) canvas.print_figure(filename)
class Browse(object): ''' Class to hold the GUI browse method ''' def __init__(self, pathDir=None, airborne=False, rhi=False): ''' Initialize the class to create the interface ''' # Set some parameters self.dirIn = pathDir # Default field and tilt angle to plot self.field = 'reflectivity' self.tilt = 0 self.airborne = airborne self.rhi = rhi # Set size of plot self.XSIZE = PPI_XSIZE self.YSIZE = PPI_YSIZE self.XRNG = PPI_XRNG self.YRNG = PPI_YRNG if self.airborne: self.XSIZE = AIR_XSIZE self.YSIZE = AIR_YSIZE self.XRNG = AIR_XRNG self.YRNG = AIR_YRNG if self.rhi: self.XSIZE = RHI_XSIZE self.YSIZE = RHI_YSIZE self.XRNG = RHI_XRNG self.YRNG = RHI_YRNG # Set the default range rings self.RngRingList = ["None", "10 km", "20 km", "30 km", "50 km", "100 km"] self.RngRing = False # Find the PyArt colormap names self.cm_names = pyart.graph.cm._cmapnames # Launch the GUI interface self.LaunchGUI() # Create a figure for output self._set_fig_ax(nrows=1, ncols=1) # Initialize limits self._initialize_limits() # Create the Limit Entry self.Make_Lims_Entry() # Show an "Open" dialog box and return the path to the selected file self._initial_openfile() # Allow advancement via left and right arrow keys self.root.bind('<Left>', self.leftkey) self.root.bind self.root.bind('<Right>', self.rightkey) self.root.bind('<Up>', self.upkey) self.root.bind('<Down>', self.downkey) self.frame.pack() self.root.update_idletasks() Tk.mainloop() #################### # GUI methods # #################### def LaunchGUI(self): '''Launches a GUI interface. Creates and returns gui and frame to pack ''' # Initiate a counter, used so that Tilt and Field menus are # not increased every time there is a selection # Might be a more elegant way self.counter = 0 self.root = Tk.Tk() self.root.title("ARTView - ARM Radar Toolkit Viewer") # Create a frame to hold the gui stuff self.frame = Tk.Frame(self.root)#, width=600, height=600 self.frame.pack() Tk.Label(self.frame).pack() # Create the menus self.CreateMenu() self.AddHelpMenu() self.AddPlotMenu() self.AddFileAdvanceMenu() ###################### # Help methods # ###################### def _about(self): print "This is a simple radar file browser to look at files using PyArt" def _dump_radar_info_to_terminal(self): '''Print out the radar info to text box''' # Get the radar info form rada object and print it radar_text = self.radar.info() print radar_text ### THIS PORTION DOES NOT WORK TO DATE ### # self.textFrame = Tk.Frame(self.root) # self.text = Tk.text(self.textFrame) # self.text.pack() # self.text.insert(self.radar_info, Tk.END, '''Radar info goes here''') def _print_radar_info_short(self): '''Print out some basic info about the radar''' print ('Radar Name: %s'% self.radar.metadata['instrument_name']) print ('Radar longitude: %f'% self.radar.longitude['data'][0]) print ('Radar latitude: %f'% self.radar.latitude['data'][0]) print ('Radar altitude: %f'% self.radar.altitude['data'][0]) print (' ') print ('Unambiguous range: %f %s' % \ (self.radar.instrument_parameters['unambiguous_range']['data'][0], \ self.radar.instrument_parameters['unambiguous_range']['units'][0])) print ('Nyquist velocity: %f %s' % \ (self.radar.instrument_parameters['nyquist_velocity']['data'][0], \ self.radar.instrument_parameters['nyquist_velocity']['units'][0])) print (' ') print ('Radar Beamwidth, horiz: %f %s' % \ (self.radar.instrument_parameters['radar_beam_width_h']['data'][0], \ self.radar.instrument_parameters['radar_beam_width_h']['units'][0])) print ('Radar Beamwidth, vert: %f %s' % \ (self.radar.instrument_parameters['radar_beam_width_v']['data'][0], \ self.radar.instrument_parameters['radar_beam_width_v']['units'][0])) print ('Pulsewidth: %f %s' % \ (self.radar.instrument_parameters['pulse_width']['data'][0], \ self.radar.instrument_parameters['pulse_width']['units'][0])) print (' ') print ('Number of gates: ', self.radar.ngates) print ('Number of sweeps: ', self.radar.nsweeps) ###################### # Menu build methods # ###################### def CreateMenu(self): '''Create a selection menu''' self.menu = Tk.Menu(self.frame) self.root.config(menu=self.menu) filemenu = Tk.Menu(self.menu) self.menu.add_cascade(label="File", menu=filemenu) filemenu.add_command(label="Open...", command=self._initial_openfile) filemenu.add_separator() filemenu.add_command(label="Save Image", command=self._savefile) filemenu.add_separator() filemenu.add_command(label="Exit", command=self._quit) def AddHelpMenu(self): '''Add Help item to menu bar''' helpmenu = Tk.Menu(self.menu) self.menu.add_cascade(label="Help", menu=helpmenu) helpmenu.add_command(label="About...", command=self._about) helpmenu.add_command(label="Print Short Radar Info", command=self._print_radar_info_short) helpmenu.add_command(label="Print Long Radar Info", command=self._dump_radar_info_to_terminal) def AddPlotMenu(self): '''Add Plot item to menu bar''' plotmenu = Tk.Menu(self.menu) self.menu.add_cascade(label="Plot", menu=plotmenu) self.fieldmenu = Tk.Menu(self.menu) self.tiltmenu = Tk.Menu(self.menu) self.rngringmenu = Tk.Menu(self.menu) # self.cmapmenu = Tk.Menu(self.menu) plotmenu.add_cascade(label="Field", menu=self.fieldmenu) if self.airborne or self.rhi: pass else: plotmenu.add_cascade(label="Tilt", menu=self.tiltmenu) plotmenu.add_cascade(label="Rng Ring every...", menu=self.rngringmenu) # plotmenu.add_cascade(label="Colormap", menu=self.cmapmenu) def AddFileAdvanceMenu(self): '''Add an option to advance to next or previous file''' self.advancemenu = Tk.Menu(self.menu) self.menu.add_cascade(label="Advance file", menu=self.advancemenu) def AddTiltMenu(self): '''Add a menu to change tilt angles of current plot''' for ntilt in self.rTilts: cmd = (lambda ntilt: lambda: self.TiltSelectCmd(ntilt)) (ntilt) self.tiltmenu.add_command(label="Tilt %d"%(ntilt+1), command=cmd) def AddFieldMenu(self): '''Add a menu to change current plot field''' for nombre in self.fieldnames: cmd = (lambda nombre: lambda: self.FieldSelectCmd(nombre)) (nombre) self.fieldmenu.add_command(label=nombre, command=cmd) def AddRngRingMenu(self): '''Add a menu to set range rings''' for RngRing in self.RngRingList: cmd = (lambda RngRing: lambda: self.RngRingSelectCmd(RngRing)) (RngRing) self.rngringmenu.add_command(label=RngRing, command=cmd) def AddNextPrevMenu(self): '''Add an option to advance to next or previous file''' nextcmd = (lambda findex: lambda: self.AdvanceFileSelect(findex)) (self.fileindex + 1) self.advancemenu.add_command(label="Next", command=nextcmd) prevcmd = (lambda findex: lambda: self.AdvanceFileSelect(findex)) (self.fileindex - 1) self.advancemenu.add_command(label="Previous", command=prevcmd) def AddCmapMenu(self): '''Add a menu to change colormap used for plot''' for cm_name in self.cm_names: cmd = (lambda cm_name: lambda: self.cmapSelectCmd(cm_name)) (cm_name) self.cmapmenu.add_command(label=cm_name, command=cmd) def _quit(self): self.root.quit() self.root.destroy() ####################### # Menu remove methods # ####################### def _remove_tilt_menu(self): '''Remove the tilt menu items''' for ntilt in self.rTilts: self.tiltmenu.delete("Tilt %d"%(ntilt+1)) def _remove_field_menu(self): '''Remove the field menu items''' for nombre in self.fieldnames: self.fieldmenu.delete(nombre) def _remove_rngring_menu(self): '''Remove the range rings menu items''' for rngring in self.RngRingList: self.rngringmenu.delete(rngring) def _remove_next_prev_menu(self): '''Remove the next and previous''' self.advancemenu.delete("Next") self.advancemenu.delete("Previous") ######################## # Button build methods # ######################## def SetTiltRadioButtons(self): '''Set a tilt selection using radio buttons''' # Create a dialog box to choose Tilt angle TiltInt = Tk.IntVar() # Create array to hold button instances tiltbutton = [] for ntilt in self.rTilts: command = (lambda ntilt: lambda: self.TiltSelectCmd(ntilt)) (ntilt) tiltbutton.append(Tk.Radiobutton(self.frame, value=int(ntilt), \ text="Tilt %d"%(ntilt+1), variable=TiltInt, \ command=command)) tiltbutton[ntilt].pack(expand=1, side=Tk.TOP, anchor="w") self.tiltbutton = tiltbutton ######################### # Button remove methods # ######################### def _remove_tilt_radiobutton(self): '''Remove the tilt selection radio buttons''' for ntilt in self.rTilts: self.tiltbutton[ntilt].destroy() ############################# # Limit entry build methods # ############################# def Make_Lims_Entry(self): '''Make entry boxes to modify variable and axis limits''' self.root.update() disp_strs = ('Data Min:', 'Data Max:', 'X-axis Min:', 'X-axis Max:', \ 'Y-axis Min:', 'Y-axis Max:') limit_strs = ('vmin', 'vmax', 'xmin', 'xmax', 'ymin', 'ymax') self.entryfield = [] self.EntryFrame = Tk.Frame(self.frame) for index, lstr in enumerate(disp_strs): LimitLabel = Tk.Label(self.EntryFrame, text=lstr) LimitLabel.pack(side=Tk.TOP) self.entryfield.append(Tk.Entry(self.EntryFrame, width=6)) self.entryfield[index].pack(expand=1, side=Tk.TOP) self.entryfield[index].insert(0, self.limits[limit_strs[index]]) # LimitLabel.update_idletasks() # self.entryfield[index].update_idletasks() self.root.update() self.EntryFrame.pack(side=Tk.LEFT) self.applybutton = Tk.Button(self.EntryFrame, text='Apply',command=self._update_lims) self.applybutton.pack(side=Tk.TOP) self.EntryFrame.bind("<Button-1>", self._update_entrylist) def _update_lims(self): '''Update the limits with newly entered limits''' limit_strs = ('vmin', 'vmax', 'xmin', 'xmax', 'ymin', 'ymax') for index, lstr in enumerate(limit_strs): self.limits[lstr] = float(self.entryfield[index].get()) # self.root.update_() # Update the plot with new values self._update_plot() def _update_entrylist(self): self.root.update_idletasks() self.EntryFrame.update_idletasks() ######################## # Selectionion methods # ######################## def TiltSelectCmd(self, ntilt): '''Captures a selection and redraws the field with new tilt''' self.tilt = ntilt self._update_plot() def FieldSelectCmd(self, nombre): '''Captures a selection and redraws the new field''' self.field = nombre self._initialize_limits() self.root.update_idletasks() self._update_plot() def RngRingSelectCmd(self, ringSel): '''Captures selection and redraws the field with range rings''' if ringSel is "None": self.RngRing = False else: self.RngRing = True # Find the unambigous range of the radar unrng = int(self.radar.instrument_parameters['unambiguous_range']['data'][0]/1000) # Set the step if ringSel == '10 km': ringdel = 10 if ringSel == '20 km': ringdel = 20 if ringSel == '30 km': ringdel = 30 if ringSel == '50 km': ringdel = 50 if ringSel == '100 km': ringdel = 100 # Calculate an array of range rings self.RNG_RINGS = range(ringdel, unrng, ringdel) self._update_plot() def cmapSelectCmd(self, cm_name): '''Captures selection of new cmap and redraws''' self.CMAP = cm_name self.root.update_idletasks() self._update_plot() def AdvanceFileSelect(self, findex): '''Captures a selection and redraws figure with new file''' if findex > len(self.filelist): print "END OF DIRECTORY, CANNOT ADVANCE" return if findex < 0: print "BEGINNING OF DIRECTORY CANNOT ADVANCE" return self.fileindex = findex self.filename = self.dirIn + "/" + self.filelist[findex] self._openfile() def leftkey(self, event): '''Left arrow key event triggers advancement''' self.AdvanceFileSelect(self.fileindex - 1) def rightkey(self, event): '''Right arrow key event triggers advancement''' self.AdvanceFileSelect(self.fileindex + 1) def upkey(self, event): '''Up arrow key event triggers tilt move''' self.TiltSelectCmd(self.tilt + 1) def downkey(self, event): '''Down arrow key event triggers tilt move''' self.TiltSelectCmd(self.tilt - 1) ######################## # Data display methods # ######################## def _initial_openfile(self): '''Open a file via a file selection window''' # self.root.update() self.filename = askopenfilename(initialdir=self.dirIn, title='Choose a file') # Reset the directory path if needed, build list for advancing self._get_directory_info() self._openfile() def _openfile(self): '''Open a file via a file selection window''' print "Opening file " + self.filename # Read the data from file try: self.radar = pyart.io.read(self.filename) except: "This is not a recognized radar file" return # In case the flags were not used at startup # Check to see if this is an aircraft or rhi file if self.counter == 0: self._check_file_type() self._set_figure_canvas() # Increment counter to know whether to renew Tilt and field menus # If > 1 then remove the pre-existing menus before redrawing self.counter += 1 if self.counter > 1: self._remove_field_menu() self._remove_next_prev_menu() #self._remove_lims_entry() if self.airborne or self.rhi: pass else: self._remove_tilt_menu() self._remove_tilt_radiobutton() self._remove_rngring_menu() # Get the tilt angles self.rTilts = self.radar.sweep_number['data'][:] # Get field names self.fieldnames = self.radar.fields.keys() # Set up the tilt and field menus if self.airborne or self.rhi: pass else: self.SetTiltRadioButtons() self.AddRngRingMenu() self.AddTiltMenu() self.AddFieldMenu() self.AddNextPrevMenu() # self.AddCmapMenu() self.root.update_idletasks() self._update_plot() self.root.update_idletasks() self.EntryFrame.update_idletasks() #################### # Plotting methods # #################### def _set_fig_ax(self, nrows=1, ncols=1): '''Set the figure and axis to plot to''' self.fig = matplotlib.figure.Figure(figsize=(self.XSIZE, self.YSIZE)) xwidth = 0.7 yheight = 0.7 * float(self.YSIZE)/float(self.XSIZE) self.ax = self.fig.add_axes([0.2, 0.2, xwidth, yheight]) self.cax = self.fig.add_axes([0.2,0.10, xwidth, 0.02]) def _set_fig_ax_rhi(self): '''Change figure size and limits if RHI''' if self.rhi: self.XSIZE = RHI_XSIZE self.YSIZE = RHI_YSIZE self.limits['ymin'] = RHI_YRNG[0] self.limits['ymax'] = RHI_YRNG[1] if self.airborne: self.XSIZE = AIR_XSIZE self.YSIZE = AIR_YSIZE self.limits['xmin'] = AIR_XRNG[0] self.limits['xmax'] = AIR_XRNG[1] self.limits['ymin'] = AIR_YRNG[0] self.limits['ymax'] = AIR_YRNG[1] self.fig.set_size_inches(self.XSIZE, self.YSIZE) self._set_fig_ax() # self.canvas.draw() def _set_figure_canvas(self): '''Set the figure canvas to draw in window area''' # a tk.DrawingArea self.canvas = FigureCanvasTkAgg(self.fig, master=self.frame)#window) self.canvas.show() self.canvas.get_tk_widget().pack(side=Tk.LEFT, expand=1) self.canvas._tkcanvas.pack(side=Tk.LEFT, expand=1)#fill=Tk.BOTH, self.canvas.draw() def _update_plot(self): '''Renew the plot''' print "Plotting " + self.field + " field, " + "Tilt %d" % (self.tilt+1) # This is a bit of a hack to ensure that the viewer works with files # withouth "standard" output as defined by PyArt # Check to see if the field 'reflectivity' exists for the initial open self._check_default_field() # Create the plot with PyArt RadarDisplay # Always intitiates at lowest elevation angle self.ax.cla() if self.airborne: self.display = pyart.graph.RadarDisplay_Airborne(self.radar) self.plot = self.display.plot_sweep_grid(self.field, \ vmin=self.limits['vmin'], vmax=self.limits['vmax'],\ colorbar_flag=False, cmap=self.CMAP,\ ax=self.ax) self.display.set_limits(xlim=(self.limits['xmin'], self.limits['xmax']),\ ylim=(self.limits['ymin'], self.limits['ymax']),\ ax=self.ax) self.display.plot_grid_lines() else: self.display = pyart.graph.RadarDisplay(self.radar) if self.radar.scan_type == 'ppi': # Create Plot self.plot = self.display.plot_ppi(self.field, self.tilt,\ vmin=self.limits['vmin'], vmax=self.limits['vmax'],\ colorbar_flag=False, cmap=self.CMAP,\ ax=self.ax) # Set limits self.display.set_limits(xlim=(self.limits['xmin'], self.limits['xmax']),\ ylim=(self.limits['ymin'], self.limits['ymax']),\ ax=self.ax) # Add range rings if self.RngRing: self.display.plot_range_rings(self.RNG_RINGS, ax=self.ax) # Add radar location self.display.plot_cross_hair(5., ax=self.ax) elif (self.radar.scan_type == 'rhi') or (self.rhi is True): self.plot = self.display.plot_rhi(self.field, self.tilt,\ vmin=self.limits['vmin'], vmax=self.limits['vmax'],\ colorbar_flag=False, cmap=self.CMAP,\ ax=self.ax) self.display.set_limits(xlim=(self.limits['xmin'], self.limits['xmax']),\ ylim=(self.limits['ymin'], self.limits['ymax']),\ ax=self.ax) # Add range rings if self.RngRing: self.display.plot_range_rings(self.RNG_RINGS, ax=self.ax) norm = matplotlib.colors.Normalize(vmin=self.limits['vmin'],\ vmax=self.limits['vmax']) self.cbar=matplotlib.colorbar.ColorbarBase(self.cax, cmap=self.CMAP,\ norm=norm, orientation='horizontal') self.cbar.set_label(self.radar.fields[self.field]['units']) self.canvas.draw() self.root.update_idletasks() ######################### # Get and check methods # ######################### def _get_directory_info(self): ''' Record the directory of file This is useful if user went somewhere else on startup ''' self.dirIn = os.path.dirname(self.filename) # Get a list of files in the working directory self.filelist = os.listdir(self.dirIn) self.fileindex = self.filelist.index(os.path.basename(self.filename)) def _initialize_limits(self): if self.field == 'reflectivity': self.vminmax = (Z_LIMS[0], Z_LIMS[1]) self.CMAP = 'gist_ncar' elif self.field == 'DBZ': self.vminmax = (Z_LIMS[0], Z_LIMS[1]) self.CMAP = 'gist_ncar' elif self.field == 'velocity': self.vminmax = (VR_LIMS[0], VR_LIMS[1]) self.CMAP = 'RdBu_r' elif self.field == 'VEL': self.vminmax = (VR_LIMS[0], VR_LIMS[1]) self.CMAP = 'RdBu_r' elif self.field == 'differential_reflectivity': self.vminmax = (ZDR_LIMS[0], ZDR_LIMS[1]) self.CMAP = 'RdYlBu_r' elif self.field == 'cross_correlation_ratio': self.vminmax = (RHO_HV_LIMS[0], RHO_HV_LIMS[1]) self.CMAP = 'cool' elif self.field == 'differential_phase': self.vminmax = (KDP_LIMS[0], KDP_LIMS[1]) self.CMAP = 'YlOrBr' elif self.field == 'normalized_coherent_power': self.vminmax = (NCP_LIMS[0], NCP_LIMS[1]) self.CMAP = 'jet' elif self.field == 'spectrum_width': self.vminmax = (SW_LIMS[0], SW_LIMS[1]) self.CMAP = 'gist_ncar' elif self.field == 'specific_differential_phase': self.vminmax = (PHIDP_LIMS[0], PHIDP_LIMS[1]) self.CMAP = 'RdBu_r' elif self.field == 'total_power': self.vminmax = (TP_LIMS[0], TP_LIMS[1]) self.CMAP = 'jet' limit_strs = ('vmin', 'vmax', 'xmin', 'xmax', 'ymin', 'ymax') self.limits = {} # Now pull the default values self.limits['vmin'] = self.vminmax[0] self.limits['vmax'] = self.vminmax[1] self.limits['xmin'] = self.XRNG[0] self.limits['xmax'] = self.XRNG[1] self.limits['ymin'] = self.YRNG[0] self.limits['ymax'] = self.YRNG[1] # def _build_cmap_dict(self): # self.cmap_dict = {} # self.cmap_dict['gist_ncar'] = matcm.get_cmap(name='gist_ncar') # self.cmap_dict['RdBu_r'] = matcm.get_cmap(name='RdBu_r') # self.cmap_dict['RdYlBu_r'] = matcm.get_cmap(name='RdYlBu_r # self.cmap_dict['cool'] = matcm.get_cmap(name='cool # self.cmap_dict['YlOrBr'] = matcm.get_cmap(name='YlOrBr # self.cmap_dict['jet'] = matcm.get_cmap(name='jet # self.cmap_dict[' # self.cmap_dict[' # self.cmap_dict[' # self.cmap_dict[' # self.cmap_dict[' # self.cmap_dict[' # self.cmap_dict[' # self.cmap_dict[' # self.cmap_dict[' # self.cmap_dict[' # self.cmap_dict[' # self.cmap_dict[' # self.cmap_dict[' # self.cmap_dict[' # self.cmap_dict[' # self.cmap_dict[' # self.cmap_dict[' # self.cmap_dict[' def _check_default_field(self): '''Hack to perform a check on reflectivity to make it work with a larger number of files This should only occur upon start up with a new file''' if self.field == 'reflectivity': if self.field in self.fieldnames: pass elif 'CZ' in self.fieldnames: self.field = 'CZ' elif 'DZ' in self.fieldnames: self.field = 'DZ' elif 'dbz' in self.fieldnames: self.field = 'dbz' elif 'DBZ' in self.fieldnames: self.field = 'DBZ' elif 'dBZ' in self.fieldnames: self.field = 'dBZ' elif 'Z' in self.fieldnames: self.field = 'Z' elif 'DBZ_S'in self.fieldnames: self.field = 'DBZ_S' def _check_file_type(self): '''Check file to see if the file is airborne or rhi''' if self.radar.scan_type == 'rhi': try: (self.radar.metadata['platform_type'] == 'aircraft_tail') or \ (self.radar.metadata['platform_type'] == 'aircraft') self.airborne = True except: self.rhi = True self._set_fig_ax_rhi() elif self.radar.scan_type == 'ppi': pass else: print "Check the scan type, ARTview supports PPI and RHI" return ######################## # Image save methods # ######################## def _savefile(self, PTYPE=PTYPE): '''Save the current display''' PNAME = self.display.generate_filename(self.field, self.tilt, ext=PTYPE) print "Creating "+ PNAME RADNAME = self.radar.metadata['instrument_name'] self.canvas.print_figure(PNAME, dpi=DPI)
def drawBatch(fig, filename): canvas = CanvasBackend(fig) canvas.print_figure(filename)