Changeset 482


Ignore:
Timestamp:
02/18/05 17:40:22 (20 years ago)
Author:
cal103
Message:

In set_panels(), disabled labelling of interior subplots and squeezed out
excess space between rows and columns in a rectangular asaplot plot array.
Implemented cursor position readback and interactive region selection via
the new position() and region() methods, though neither of these will work
properly until a blocking mechanism is added to matplotlib (a known
deficiency).

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/python/asaplot.py

    r411 r482  
    77import Tkinter as Tk
    88
    9 #print "Importing matplotlib with TkAgg backend."
    109import matplotlib
    1110matplotlib.use("TkAgg")
     
    1615from matplotlib.figure import Figure, Text
    1716from matplotlib.numerix import sqrt
    18 from matplotlib import rc,rcParams
     17from matplotlib import rc, rcParams
    1918
    2019# Force use of the newfangled toolbar.
     
    2928    """
    3029
    31     def __init__(self, rows=1, cols=0, title='', size=(7,5), buffering=False):
     30    def __init__(self, rows=1, cols=0, title='', size=(8,6), buffering=False):
    3231        """
    3332        Create a new instance of the ASAPlot plotting class.
     
    3736        """
    3837        self.window = Tk.Tk()
    39         self.is_dead = False
    40         def dest_callback():
    41             self.is_dead = True
    42             self.window.destroy()
    43        
    44         self.window.protocol("WM_DELETE_WINDOW", dest_callback)
    45         #self.frame1 = Tk.Frame(self.window, relief=Tk.RIDGE, borderwidth=4)
    46         #self.frame1.pack(fill=Tk.BOTH)
    47 
    48         self.figure = Figure(figsize=size,facecolor='#ddddee')
     38        self.is_dead = False
     39        def dest_callback():
     40            self.is_dead = True
     41            self.window.destroy()
     42
     43        self.window.protocol("WM_DELETE_WINDOW", dest_callback)
     44
     45        self.figure = Figure(figsize=size, facecolor='#ddddee')
    4946        self.canvas = FigureCanvasTkAgg(self.figure, master=self.window)
    5047        self.canvas.get_tk_widget().pack(side=Tk.TOP, fill=Tk.BOTH, expand=1)
     
    7168        matplotlib.interactive = True
    7269        self.buffering = buffering
    73        
     70
    7471        self.canvas.show()
    7572
     
    8683        self.colours[0] = 1
    8784        self.lines = []
    88        
     85
    8986
    9087    def delete(self, numbers=None):
     
    298295
    299296
     297    def position(self):
     298        """
     299        Use the mouse to get a position from a graph.
     300        """
     301
     302        def position_disable(event):
     303            self.register('button_press', None)
     304            print '%.4f, %.4f' % (event.xdata, event.ydata)
     305
     306        print 'Press any mouse button...'
     307        self.register('button_press', position_disable)
     308
     309
    300310    def quit(self):
    301311        """
     
    303313        """
    304314        self.window.destroy()
     315
     316
     317    def region(self):
     318        """
     319        Use the mouse to get a rectangular region from a plot.
     320
     321        The return value is [x0, y0, x1, y1] in world coordinates.
     322        """
     323
     324        def region_start(event):
     325            height = self.canvas.figure.bbox.height()
     326            self.rect = {'fig': None, 'height': height,
     327                         'x': event.x, 'y': height - event.y,
     328                         'world': [event.xdata, event.ydata,
     329                                   event.xdata, event.ydata]}
     330            self.register('button_press', None)
     331            self.register('motion_notify', region_draw)
     332            self.register('button_release', region_disable)
     333
     334        def region_draw(event):
     335            self.canvas._tkcanvas.delete(self.rect['fig'])
     336            self.rect['fig'] = self.canvas._tkcanvas.create_rectangle(
     337                                self.rect['x'], self.rect['y'],
     338                                event.x, self.rect['height'] - event.y)
     339
     340        def region_disable(event):
     341            self.register('motion_notify', None)
     342            self.register('button_release', None)
     343
     344            self.canvas._tkcanvas.delete(self.rect['fig'])
     345
     346            self.rect['world'][2:4] = [event.xdata, event.ydata]
     347            print '(%.2f, %.2f)  (%.2f, %.2f)' % (self.rect['world'][0],
     348                self.rect['world'][1], self.rect['world'][2],
     349                self.rect['world'][3])
     350
     351        self.register('button_press', region_start)
     352
     353        # This has to be modified to block and return the result (currently
     354        # printed by region_disable) when that becomes possible in matplotlib.
     355
     356        return [0.0, 0.0, 0.0, 0.0]
    305357
    306358
     
    309361        Register, reregister, or deregister events of type 'button_press',
    310362        'button_release', or 'motion_notify'.
    311        
     363
    312364        The specified callback function should have the following signature:
    313365
     
    371423
    372424
     425    def save(self, fname=None):
     426        """
     427        Save the plot to a file.
     428
     429        fname is the name of the output file.  The image format is determined
     430        from the file suffix; 'png', 'ps', and 'eps' are recognized.  If no
     431        file name is specified 'yyyymmdd_hhmmss.png' is created in the current
     432        directory.
     433        """
     434        if fname is None:
     435            from datetime import datetime
     436            dstr = datetime.now().strftime('%Y%m%d_%H%M%S')
     437            fname = 'asap'+dstr+'.png'
     438
     439        d = ['png','.ps','eps']
     440
     441        from os.path import expandvars
     442        fname = expandvars(fname)
     443
     444        if fname[-3:].lower() in d:
     445            try:
     446                self.canvas.print_figure(fname)
     447                print 'Written file %s' % (fname)
     448            except IOError, msg:
     449                print 'Failed to save %s: Error msg was\n\n%s' % (fname, err)
     450                return
     451        else:
     452            print "Invalid image type. Valid types are:"
     453            print "ps, eps, png"
     454
     455
    373456    def set_axes(self, what=None, *args, **kwargs):
    374457        """
     
    419502        getattr(self.figure, "set_%s"%what)(*args, **newargs)
    420503        self.show()
     504
     505
     506    def set_limits(self, xlim=None, ylim=None):
     507        """
     508        Set x-, and y-limits for each subplot.
     509
     510        xlim = [xmin, xmax] as in axes.set_xlim().
     511        ylim = [ymin, ymax] as in axes.set_ylim().
     512        """
     513
     514        for s in self.subplots:
     515            self.axes  = s['axes']
     516            self.lines = s['lines']
     517            if xlim is not None:
     518                self.axes.set_xlim(xlim)
     519            if ylim is not None:
     520                self.axes.set_ylim(ylim)
     521        return
    421522
    422523
     
    469570        """
    470571        Set the panel layout.
    471        
     572
    472573        rows and cols, if cols != 0, specify the number of rows and columns in
    473574        a regular layout.   (Indexing of these panels in matplotlib is row-
     
    483584        non-regular panel layouts to be constructed via multiple calls.  Any
    484585        other value of n clears the plot and produces a rectangular array of
    485         empty panels.
     586        empty panels.  The number of these may be limited by nplots.
    486587        """
    487588        if n < 0 and len(self.subplots):
     
    489590            self.set_title()
    490591
    491         if rows < 1:
    492             rows = 1
    493         nel = 1
    494         if cols == 0:
    495             nel = rows
     592        if rows < 1: rows = 1
     593
     594        if cols <= 0:
    496595            i = int(sqrt(rows))
    497596            if i*i < rows: i += 1
     
    500599            if i*(i-1) >= rows: i -= 1
    501600            rows = i
    502         else:
    503             if nplots > -1:
    504                 nel=nplots
     601
    505602        if 0 <= n < rows*cols:
    506603            i = len(self.subplots)
    507604            self.subplots.append({})
     605
    508606            self.subplots[i]['axes']  = self.figure.add_subplot(rows,
    509607                                            cols, n+1)
     
    512610            if i == 0: self.subplot(0)
    513611
     612            self.rows = 0
     613            self.cols = 0
     614
    514615        else:
    515616            self.subplots = []
    516             for i in range(nel):
     617
     618            if nplots < 1 or rows*cols < nplots:
     619                nplots = rows*cols
     620
     621            for i in range(nplots):
    517622                self.subplots.append({})
     623
    518624                self.subplots[i]['axes']  = self.figure.add_subplot(rows,
    519625                                                cols, i+1)
    520626                self.subplots[i]['lines'] = []
    521627
     628                if rows > 1 or cols > 1:
     629                    # Squeeze the plots together.
     630                    pos = self.subplots[i]['axes'].get_position()
     631                    if cols > 1: pos[2] *= 1.1
     632                    if rows > 1: pos[3] *= 1.1
     633                    self.subplots[i]['axes'].set_position(pos)
     634
     635                # Suppress tick labelling for interior subplots.
     636                if i <= (rows-1)*cols - 1:
     637                    # Suppress x-labels for frames not in the bottom row.
     638                    self.subplots[i]['axes'].set_xticklabels([])
     639
     640                if i%cols:
     641                    # Suppress y-labels for frames not in the left column.
     642                    self.subplots[i]['axes'].set_yticklabels([])
     643
     644                self.rows = rows
     645                self.cols = cols
     646
    522647            self.subplot(0)
    523648
     
    540665        if not self.buffering:
    541666            if self.loc:
    542                 for j in range(len(self.subplots)):
    543                     lines  = []
    544                     labels = []
    545                     i = 0
    546                     for line in self.subplots[j]['lines']:
    547                         i += 1
    548                         if line is not None:
    549                             lines.append(line[0])
    550                             lbl = line[0].get_label()
    551                             if lbl == '':
    552                                 lbl = str(i)
    553                             labels.append(lbl)
    554 
    555                     if len(lines):
    556                         self.subplots[j]['axes'].legend(tuple(lines), tuple(labels), self.loc)
    557                     else:
    558                         self.subplots[j]['axes'].legend((' '))
     667                for j in range(len(self.subplots)):
     668                    lines  = []
     669                    labels = []
     670                    i = 0
     671                    for line in self.subplots[j]['lines']:
     672                        i += 1
     673                        if line is not None:
     674                            lines.append(line[0])
     675                            lbl = line[0].get_label()
     676                            if lbl == '':
     677                                lbl = str(i)
     678                            labels.append(lbl)
     679
     680                    if len(lines):
     681                        self.subplots[j]['axes'].legend(tuple(lines),
     682                                                        tuple(labels),
     683                                                        self.loc)
     684                    else:
     685                        self.subplots[j]['axes'].legend((' '))
    559686
    560687            self.window.wm_deiconify()
     
    592719        """
    593720        self.figure.text(*args, **kwargs)
    594         self.show()       
     721        self.show()
     722
    595723
    596724    def unmap(self):
     
    599727        """
    600728        self.window.wm_withdraw()
    601 
    602     def set_limits(self,xlim=None,ylim=None):
    603         for s in self.subplots:
    604             self.axes  = s['axes']
    605             self.lines = s['lines']
    606             if xlim is not None:
    607                 self.axes.set_xlim(xlim)
    608             if ylim is not None:
    609                 self.axes.set_ylim(ylim)
    610         return
    611 
    612     def save(self, fname=None):
    613         """
    614         Save the plot to a file. The know formats are 'png', 'ps', 'eps'.
    615         Parameters:
    616              filename:    The name of the output file. This is optional
    617                           and autodetects the image format from the file
    618                           suffix. If non filename is specified a file
    619                           called 'yyyymmdd_hhmmss.png' is created in the
    620                           current directory.
    621         """
    622         if fname is None:
    623             from datetime import datetime
    624             dstr = datetime.now().strftime('%Y%m%d_%H%M%S')
    625             fname = 'asap'+dstr+'.png'
    626            
    627         d = ['png','.ps','eps']
    628 
    629         from os.path import expandvars
    630         fname = expandvars(fname)
    631 
    632         if fname[-3:].lower() in d:
    633             try:
    634                 self.canvas.print_figure(fname)
    635                 print 'Written file %s' % (fname)
    636             except IOError, msg:
    637                 print 'Failed to save %s: Error msg was\n\n%s' % (fname, err)
    638                 return
    639         else:
    640             print "Invalid image type. Valid types are:"
    641             print "ps, eps, png"
    642729
    643730
     
    684771    Load the colour dictionary from the specified file.
    685772    """
    686     print 'Loading colour dictionary from', file
     773    print 'Loading colour dictionary from', filename
    687774    from os.path import expandvars
    688775    filename = expandvars(filename)
Note: See TracChangeset for help on using the changeset viewer.