Example #1
0
File: read.py Project: zoidy/puq
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)
Example #2
0
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)
Example #3
0
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()
Example #4
0
def drawBatch(fig,filename):
    canvas=CanvasBackend(fig)    
    canvas.print_figure(filename)
Example #5
0
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)
Example #6
0
def drawBatch(fig, filename):
    canvas = CanvasBackend(fig)
    canvas.print_figure(filename)