Changeset 1019 for trunk


Ignore:
Timestamp:
04/18/06 15:56:37 (19 years ago)
Author:
mar637
Message:

some work on the multipanel cosmetics. Use font-scaling on labels, also drop the last xaxis tick if there is an adjacent panel.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/python/asaplotbase.py

    r710 r1019  
    1414from asap import rcParams as asaprcParams
    1515
     16from matplotlib.ticker import ScalarFormatter
     17from matplotlib.ticker import NullLocator
     18
     19class MyFormatter(ScalarFormatter):
     20    def __call__(self, x, pos=None):
     21        last = len(self.locs)-2
     22        if pos==last:
     23            print "Diabling tick no " , pos, last
     24            return ''  # pos=-1 is the last tick
     25        else: return ScalarFormatter.__call__(self, x, pos)
     26
    1627class asaplotbase:
    1728    """
     
    2031
    2132    def __init__(self, rows=1, cols=0, title='', size=(8,6), buffering=False):
    22         """
    23         Create a new instance of the ASAPlot plotting class.
    24 
    25         If rows < 1 then a separate call to set_panels() is required to define
    26         the panel layout; refer to the doctext for set_panels().
    27         """
     33        """
     34        Create a new instance of the ASAPlot plotting class.
     35
     36        If rows < 1 then a separate call to set_panels() is required to define
     37        the panel layout; refer to the doctext for set_panels().
     38        """
    2839        self.is_dead = False
    29         self.figure = Figure(figsize=size, facecolor='#ddddee')
     40        self.figure = Figure(figsize=size, facecolor='#ddddee')
    3041        self.canvas = None
    3142
    32         self.set_title(title)
    33         self.subplots = []
    34         if rows > 0:
    35             self.set_panels(rows, cols)
     43        self.set_title(title)
     44        self.subplots = []
     45        if rows > 0:
     46            self.set_panels(rows, cols)
    3647
    3748        # Set matplotlib default colour sequence.
    3849        self.colormap = "green red black cyan magenta orange blue purple yellow pink".split()
    39        
     50
    4051        c = asaprcParams['plotter.colours']
    4152        if isinstance(c,str) and len(c) > 0:
     
    6475        self.color = 0;
    6576        self.linestyle = 0;
    66         self.attributes = {}
    67         self.loc = 0
    68 
    69         self.buffering = buffering
     77        self.attributes = {}
     78        self.loc = 0
     79
     80        self.buffering = buffering
    7081
    7182    def clear(self):
    72         """
    73         Delete all lines from the plot.  Line numbering will restart from 1.
    74         """
    75 
    76         for i in range(len(self.lines)):
    77            self.delete(i)
    78         self.axes.clear()
    79         self.color = 0
    80         self.lines = []
     83        """
     84        Delete all lines from the plot.  Line numbering will restart from 1.
     85        """
     86
     87        for i in range(len(self.lines)):
     88           self.delete(i)
     89        self.axes.clear()
     90        self.color = 0
     91        self.lines = []
    8192
    8293    def palette(self, color, colormap=None, linestyle=0, linestyles=None):
     
    103114
    104115    def delete(self, numbers=None):
    105         """
    106         Delete the 0-relative line number, default is to delete the last.
    107         The remaining lines are NOT renumbered.
    108         """
    109 
    110         if numbers is None: numbers = [len(self.lines)-1]
    111 
    112         if not hasattr(numbers, '__iter__'):
    113             numbers = [numbers]
    114 
    115         for number in numbers:
    116             if 0 <= number < len(self.lines):
    117                 if self.lines[number] is not None:
    118                     for line in self.lines[number]:
    119                         line.set_linestyle('None')
    120                         self.lines[number] = None
    121         self.show()       
     116        """
     117        Delete the 0-relative line number, default is to delete the last.
     118        The remaining lines are NOT renumbered.
     119        """
     120
     121        if numbers is None: numbers = [len(self.lines)-1]
     122
     123        if not hasattr(numbers, '__iter__'):
     124            numbers = [numbers]
     125
     126        for number in numbers:
     127            if 0 <= number < len(self.lines):
     128                if self.lines[number] is not None:
     129                    for line in self.lines[number]:
     130                        line.set_linestyle('None')
     131                        self.lines[number] = None
     132        self.show()
    122133
    123134    def get_line(self):
    124         """
    125         Get the current default line attributes.
    126         """
    127         return self.attributes
     135        """
     136        Get the current default line attributes.
     137        """
     138        return self.attributes
    128139
    129140
    130141    def hist(self, x=None, y=None, fmt=None):
    131         """
    132         Plot a histogram.  N.B. the x values refer to the start of the
    133         histogram bin.
    134 
    135         fmt is the line style as in plot().
    136         """
    137 
    138         if x is None:
    139             if y is None: return
    140             x = range(0,len(y))
    141 
    142         if len(x) != len(y):
    143             return
    144 
    145         l2 = 2*len(x)
    146         x2 = range(0,l2)
    147         y2 = range(0,l2)
    148 
    149         for i in range(0,l2):
    150             x2[i] = x[i/2]
    151 
    152         y2[0] = 0
    153         for i in range(1,l2):
    154             y2[i] = y[(i-1)/2]
    155 
    156         self.plot(x2, y2, fmt)
     142        """
     143        Plot a histogram.  N.B. the x values refer to the start of the
     144        histogram bin.
     145
     146        fmt is the line style as in plot().
     147        """
     148
     149        if x is None:
     150            if y is None: return
     151            x = range(0,len(y))
     152
     153        if len(x) != len(y):
     154            return
     155
     156        l2 = 2*len(x)
     157        x2 = range(0,l2)
     158        y2 = range(0,l2)
     159
     160        for i in range(0,l2):
     161            x2[i] = x[i/2]
     162
     163        y2[0] = 0
     164        for i in range(1,l2):
     165            y2[i] = y[(i-1)/2]
     166
     167        self.plot(x2, y2, fmt)
    157168
    158169
    159170    def hold(self, hold=True):
    160         """
    161         Buffer graphics until subsequently released.
    162         """
    163         self.buffering = hold
     171        """
     172        Buffer graphics until subsequently released.
     173        """
     174        self.buffering = hold
    164175
    165176
    166177    def legend(self, loc=None):
    167         """
    168         Add a legend to the plot.
    169 
    170         Any other value for loc else disables the legend:
    171              1: upper right
    172              2: upper left
    173              3: lower left
    174              4: lower right
    175              5: right
    176              6: center left
    177              7: center right
    178              8: lower center
    179              9: upper center
    180             10: center
    181 
    182         """
     178        """
     179        Add a legend to the plot.
     180
     181        Any other value for loc else disables the legend:
     182             1: upper right
     183             2: upper left
     184             3: lower left
     185             4: lower right
     186             5: right
     187             6: center left
     188             7: center right
     189             8: lower center
     190             9: upper center
     191            10: center
     192
     193        """
    183194        if isinstance(loc,int):
    184195            if 0 > loc > 10: loc = 0
    185196            self.loc = loc
    186         self.show()
     197        self.show()
    187198
    188199
    189200    def plot(self, x=None, y=None, mask=None, fmt=None, add=None):
    190         """
    191         Plot the next line in the current frame using the current line
    192         attributes.  The ASAPlot graphics window will be mapped and raised.
    193 
    194         The argument list works a bit like the matlab plot() function.
    195         """
    196 
    197         if x is None:
    198             if y is None: return
    199             x = range(len(y))
    200 
    201         elif y is None:
    202             y = x
    203             x = range(len(y))
    204 
    205         if mask is None:
    206             if fmt is None:
    207                 line = self.axes.plot(x, y)
    208             else:
    209                 line = self.axes.plot(x, y, fmt)
    210         else:
    211             segments = []
    212 
    213             mask = list(mask)
    214             i = 0
    215             while mask[i:].count(1):
    216                 i += mask[i:].index(1)
    217                 if mask[i:].count(0):
    218                     j = i + mask[i:].index(0)
    219                 else:
    220                     j = len(mask)
    221 
    222                 segments.append(x[i:j])
    223                 segments.append(y[i:j])
    224 
    225                 i = j
    226 
    227             line = self.axes.plot(*segments)
    228 
    229         # Add to an existing line?
    230         if add is None or len(self.lines) < add < 0:
    231             # Don't add.
    232             self.lines.append(line)
    233             i = len(self.lines) - 1
    234         else:
    235             if add == 0: add = len(self.lines)
    236             i = add - 1
    237             self.lines[i].extend(line)
    238 
    239         # Set/reset attributes for the line.
    240         gotcolour = False
    241         for k, v in self.attributes.iteritems():
    242             if k == 'color': gotcolour = True
    243             for segment in self.lines[i]:
    244                 getattr(segment, "set_%s"%k)(v)
    245 
    246         if not gotcolour and len(self.colormap):
    247             for segment in self.lines[i]:
    248                 getattr(segment, "set_color")(self.colormap[self.color])
     201        """
     202        Plot the next line in the current frame using the current line
     203        attributes.  The ASAPlot graphics window will be mapped and raised.
     204
     205        The argument list works a bit like the matlab plot() function.
     206        """
     207
     208        if x is None:
     209            if y is None: return
     210            x = range(len(y))
     211
     212        elif y is None:
     213            y = x
     214            x = range(len(y))
     215
     216        if mask is None:
     217            if fmt is None:
     218                line = self.axes.plot(x, y)
     219            else:
     220                line = self.axes.plot(x, y, fmt)
     221        else:
     222            segments = []
     223
     224            mask = list(mask)
     225            i = 0
     226            while mask[i:].count(1):
     227                i += mask[i:].index(1)
     228                if mask[i:].count(0):
     229                    j = i + mask[i:].index(0)
     230                else:
     231                    j = len(mask)
     232
     233                segments.append(x[i:j])
     234                segments.append(y[i:j])
     235
     236                i = j
     237
     238            line = self.axes.plot(*segments)
     239        # Add to an existing line?
     240        if add is None or len(self.lines) < add < 0:
     241            # Don't add.
     242            self.lines.append(line)
     243            i = len(self.lines) - 1
     244        else:
     245            if add == 0: add = len(self.lines)
     246            i = add - 1
     247            self.lines[i].extend(line)
     248
     249        # Set/reset attributes for the line.
     250        gotcolour = False
     251        for k, v in self.attributes.iteritems():
     252            if k == 'color': gotcolour = True
     253            for segment in self.lines[i]:
     254                getattr(segment, "set_%s"%k)(v)
     255
     256        if not gotcolour and len(self.colormap):
     257            for segment in self.lines[i]:
     258                getattr(segment, "set_color")(self.colormap[self.color])
    249259                if len(self.colormap)  == 1:
    250260                    getattr(segment, "set_dashes")(self.linestyles[self.linestyle])
    251             self.color += 1
    252             if self.color >= len(self.colormap):
    253                 self.color = 0
     261            self.color += 1
     262            if self.color >= len(self.colormap):
     263                self.color = 0
    254264
    255265            if len(self.colormap) == 1:
    256266                self.linestyle += 1
    257             if self.linestyle >= len(self.linestyles):
    258                 self.linestyle = 0               
    259 
    260         self.show()
     267            if self.linestyle >= len(self.linestyles):
     268                self.linestyle = 0
     269
     270        self.show()
    261271
    262272
    263273    def position(self):
    264         """
    265         Use the mouse to get a position from a graph.
    266         """
    267 
    268         def position_disable(event):
    269             self.register('button_press', None)
    270             print '%.4f, %.4f' % (event.xdata, event.ydata)
    271 
    272         print 'Press any mouse button...'
    273         self.register('button_press', position_disable)
     274        """
     275        Use the mouse to get a position from a graph.
     276        """
     277
     278        def position_disable(event):
     279            self.register('button_press', None)
     280            print '%.4f, %.4f' % (event.xdata, event.ydata)
     281
     282        print 'Press any mouse button...'
     283        self.register('button_press', position_disable)
    274284
    275285
    276286    def region(self):
    277         """
    278         Use the mouse to get a rectangular region from a plot.
    279 
    280         The return value is [x0, y0, x1, y1] in world coordinates.
    281         """
    282 
    283         def region_start(event):
    284             height = self.canvas.figure.bbox.height()
    285             self.rect = {'fig': None, 'height': height,
    286                         'x': event.x, 'y': height - event.y,
    287                         'world': [event.xdata, event.ydata,
    288                                    event.xdata, event.ydata]}
    289             self.register('button_press', None)
    290             self.register('motion_notify', region_draw)
    291             self.register('button_release', region_disable)
    292 
    293         def region_draw(event):
    294             self.canvas._tkcanvas.delete(self.rect['fig'])
    295             self.rect['fig'] = self.canvas._tkcanvas.create_rectangle(
    296                                 self.rect['x'], self.rect['y'],
    297                                 event.x, self.rect['height'] - event.y)
    298 
    299         def region_disable(event):
    300             self.register('motion_notify', None)
    301             self.register('button_release', None)
    302 
    303             self.canvas._tkcanvas.delete(self.rect['fig'])
    304 
    305             self.rect['world'][2:4] = [event.xdata, event.ydata]
    306             print '(%.2f, %.2f)  (%.2f, %.2f)' % (self.rect['world'][0],
    307                 self.rect['world'][1], self.rect['world'][2],
    308                 self.rect['world'][3])
    309 
    310         self.register('button_press', region_start)
    311 
    312         # This has to be modified to block and return the result (currently
    313         # printed by region_disable) when that becomes possible in matplotlib.
    314 
    315         return [0.0, 0.0, 0.0, 0.0]
     287        """
     288        Use the mouse to get a rectangular region from a plot.
     289
     290        The return value is [x0, y0, x1, y1] in world coordinates.
     291        """
     292
     293        def region_start(event):
     294            height = self.canvas.figure.bbox.height()
     295            self.rect = {'fig': None, 'height': height,
     296                        'x': event.x, 'y': height - event.y,
     297                        'world': [event.xdata, event.ydata,
     298                                   event.xdata, event.ydata]}
     299            self.register('button_press', None)
     300            self.register('motion_notify', region_draw)
     301            self.register('button_release', region_disable)
     302
     303        def region_draw(event):
     304            self.canvas._tkcanvas.delete(self.rect['fig'])
     305            self.rect['fig'] = self.canvas._tkcanvas.create_rectangle(
     306                                self.rect['x'], self.rect['y'],
     307                                event.x, self.rect['height'] - event.y)
     308
     309        def region_disable(event):
     310            self.register('motion_notify', None)
     311            self.register('button_release', None)
     312
     313            self.canvas._tkcanvas.delete(self.rect['fig'])
     314
     315            self.rect['world'][2:4] = [event.xdata, event.ydata]
     316            print '(%.2f, %.2f)  (%.2f, %.2f)' % (self.rect['world'][0],
     317                self.rect['world'][1], self.rect['world'][2],
     318                self.rect['world'][3])
     319
     320        self.register('button_press', region_start)
     321
     322        # This has to be modified to block and return the result (currently
     323        # printed by region_disable) when that becomes possible in matplotlib.
     324
     325        return [0.0, 0.0, 0.0, 0.0]
    316326
    317327
    318328    def register(self, type=None, func=None):
    319         """
    320         Register, reregister, or deregister events of type 'button_press',
    321         'button_release', or 'motion_notify'.
    322 
    323         The specified callback function should have the following signature:
    324 
    325             def func(event)
    326 
    327         where event is an MplEvent instance containing the following data:
    328 
    329             name                # Event name.
    330             canvas              # FigureCanvas instance generating the event.
    331             x      = None       # x position - pixels from left of canvas.
    332             y      = None       # y position - pixels from bottom of canvas.
    333             button = None       # Button pressed: None, 1, 2, 3.
    334             key    = None       # Key pressed: None, chr(range(255)), shift,
    335                                   win, or control
    336             inaxes = None       # Axes instance if cursor within axes.
    337             xdata  = None       # x world coordinate.
    338             ydata  = None       # y world coordinate.
    339 
    340         For example:
    341 
    342             def mouse_move(event):
    343                 print event.xdata, event.ydata
    344 
    345             a = asaplot()
    346             a.register('motion_notify', mouse_move)
    347 
    348         If func is None, the event is deregistered.
    349 
    350         Note that in TkAgg keyboard button presses don't generate an event.
    351         """
    352 
    353         if not self.events.has_key(type): return
    354 
    355         if func is None:
    356             if self.events[type] is not None:
    357                 # It's not clear that this does anything.
    358                 self.canvas.mpl_disconnect(self.events[type])
    359                 self.events[type] = None
    360 
    361                 # It seems to be necessary to return events to the toolbar.
    362                 if type == 'motion_notify':
    363                     self.canvas.mpl_connect(type + '_event',
    364                         self.figmgr.toolbar.mouse_move)
    365                 elif type == 'button_press':
    366                     self.canvas.mpl_connect(type + '_event',
    367                         self.figmgr.toolbar.press)
    368                 elif type == 'button_release':
    369                     self.canvas.mpl_connect(type + '_event',
    370                         self.figmgr.toolbar.release)
    371 
    372         else:
    373             self.events[type] = self.canvas.mpl_connect(type + '_event', func)
     329        """
     330        Register, reregister, or deregister events of type 'button_press',
     331        'button_release', or 'motion_notify'.
     332
     333        The specified callback function should have the following signature:
     334
     335            def func(event)
     336
     337        where event is an MplEvent instance containing the following data:
     338
     339            name                # Event name.
     340            canvas              # FigureCanvas instance generating the event.
     341            x      = None       # x position - pixels from left of canvas.
     342            y      = None       # y position - pixels from bottom of canvas.
     343            button = None       # Button pressed: None, 1, 2, 3.
     344            key    = None       # Key pressed: None, chr(range(255)), shift,
     345                                  win, or control
     346            inaxes = None       # Axes instance if cursor within axes.
     347            xdata  = None       # x world coordinate.
     348            ydata  = None       # y world coordinate.
     349
     350        For example:
     351
     352            def mouse_move(event):
     353                print event.xdata, event.ydata
     354
     355            a = asaplot()
     356            a.register('motion_notify', mouse_move)
     357
     358        If func is None, the event is deregistered.
     359
     360        Note that in TkAgg keyboard button presses don't generate an event.
     361        """
     362
     363        if not self.events.has_key(type): return
     364
     365        if func is None:
     366            if self.events[type] is not None:
     367                # It's not clear that this does anything.
     368                self.canvas.mpl_disconnect(self.events[type])
     369                self.events[type] = None
     370
     371                # It seems to be necessary to return events to the toolbar.
     372                if type == 'motion_notify':
     373                    self.canvas.mpl_connect(type + '_event',
     374                        self.figmgr.toolbar.mouse_move)
     375                elif type == 'button_press':
     376                    self.canvas.mpl_connect(type + '_event',
     377                        self.figmgr.toolbar.press)
     378                elif type == 'button_release':
     379                    self.canvas.mpl_connect(type + '_event',
     380                        self.figmgr.toolbar.release)
     381
     382        else:
     383            self.events[type] = self.canvas.mpl_connect(type + '_event', func)
    374384
    375385
    376386    def release(self):
    377         """
    378         Release buffered graphics.
    379         """
    380         self.buffering = False
    381         self.show()
     387        """
     388        Release buffered graphics.
     389        """
     390        self.buffering = False
     391        self.show()
    382392
    383393
    384394    def save(self, fname=None, orientation=None, dpi=None):
    385         """
    386         Save the plot to a file.
    387 
    388         fname is the name of the output file.  The image format is determined
    389         from the file suffix; 'png', 'ps', and 'eps' are recognized.  If no
    390         file name is specified 'yyyymmdd_hhmmss.png' is created in the current
    391         directory.
    392         """
    393         if fname is None:
    394             from datetime import datetime
    395             dstr = datetime.now().strftime('%Y%m%d_%H%M%S')
    396             fname = 'asap'+dstr+'.png'
    397 
    398         d = ['png','.ps','eps']
    399 
    400         from os.path import expandvars
    401         fname = expandvars(fname)
    402 
    403         if fname[-3:].lower() in d:
    404             try:
     395        """
     396        Save the plot to a file.
     397
     398        fname is the name of the output file.  The image format is determined
     399        from the file suffix; 'png', 'ps', and 'eps' are recognized.  If no
     400        file name is specified 'yyyymmdd_hhmmss.png' is created in the current
     401        directory.
     402        """
     403        if fname is None:
     404            from datetime import datetime
     405            dstr = datetime.now().strftime('%Y%m%d_%H%M%S')
     406            fname = 'asap'+dstr+'.png'
     407
     408        d = ['png','.ps','eps']
     409
     410        from os.path import expandvars
     411        fname = expandvars(fname)
     412
     413        if fname[-3:].lower() in d:
     414            try:
    405415                if fname[-3:].lower() == ".ps":
    406416                    w = self.figure.figwidth.get()
    407                     h = self.figure.figheight.get()                       
     417                    h = self.figure.figheight.get()
    408418                    a4w = 8.25
    409419                    a4h = 11.25
    410                    
     420
    411421                    if orientation is None:
    412422                        # auto oriented
     
    425435                    self.canvas.print_figure(fname,orientation=orientation)
    426436                    print 'Written file %s' % (fname)
    427                 else:                   
     437                else:
    428438                    if dpi is None:
    429439                        dpi =150
    430440                    self.canvas.print_figure(fname,dpi=dpi)
    431441                    print 'Written file %s' % (fname)
    432             except IOError, msg:
    433                 print 'Failed to save %s: Error msg was\n\n%s' % (fname, err)
    434                 return
    435         else:
    436             print "Invalid image type. Valid types are:"
    437             print "'ps', 'eps', 'png'"
     442            except IOError, msg:
     443                print 'Failed to save %s: Error msg was\n\n%s' % (fname, err)
     444                return
     445        else:
     446            print "Invalid image type. Valid types are:"
     447            print "'ps', 'eps', 'png'"
    438448
    439449
    440450    def set_axes(self, what=None, *args, **kwargs):
    441         """
    442         Set attributes for the axes by calling the relevant Axes.set_*()
    443         method.  Colour translation is done as described in the doctext
    444         for palette().
    445         """
    446 
    447         if what is None: return
    448         if what[-6:] == 'colour': what = what[:-6] + 'color'
    449 
    450         newargs = {}
    451        
    452         for k, v in kwargs.iteritems():
    453             k = k.lower()
    454             if k == 'colour': k = 'color'
    455             newargs[k] = v
    456 
    457         getattr(self.axes, "set_%s"%what)(*args, **newargs)
    458         self.show()
     451        """
     452        Set attributes for the axes by calling the relevant Axes.set_*()
     453        method.  Colour translation is done as described in the doctext
     454        for palette().
     455        """
     456
     457        if what is None: return
     458        if what[-6:] == 'colour': what = what[:-6] + 'color'
     459
     460        newargs = {}
     461
     462        for k, v in kwargs.iteritems():
     463            k = k.lower()
     464            if k == 'colour': k = 'color'
     465            newargs[k] = v
     466
     467        getattr(self.axes, "set_%s"%what)(*args, **newargs)
     468        s = self.axes.title.get_size()
     469        tsize = s-(self.cols+self.rows)/2-1
     470        self.axes.title.set_size(tsize)
     471        if self.cols > 1:
     472            xfsize = self.axes.xaxis.label.get_size()-(self.cols+1)/2
     473            self.axes.xaxis.label.set_size(xfsize)
     474        if self.rows > 1:
     475            yfsize = self.axes.yaxis.label.get_size()-(self.rows+1)/2
     476            self.axes.yaxis.label.set_size(yfsize)
     477
     478        self.show()
    459479
    460480
    461481    def set_figure(self, what=None, *args, **kwargs):
    462         """
    463         Set attributes for the figure by calling the relevant Figure.set_*()
    464         method.  Colour translation is done as described in the doctext
    465         for palette().
    466         """
    467 
    468         if what is None: return
    469         if what[-6:] == 'colour': what = what[:-6] + 'color'
    470         #if what[-5:] == 'color' and len(args):
    471         #    args = (get_colour(args[0]),)
    472 
    473         newargs = {}
    474         for k, v in kwargs.iteritems():
    475             k = k.lower()
    476             if k == 'colour': k = 'color'
    477             newargs[k] = v
    478 
    479         getattr(self.figure, "set_%s"%what)(*args, **newargs)
    480         self.show()
     482        """
     483        Set attributes for the figure by calling the relevant Figure.set_*()
     484        method.  Colour translation is done as described in the doctext
     485        for palette().
     486        """
     487
     488        if what is None: return
     489        if what[-6:] == 'colour': what = what[:-6] + 'color'
     490        #if what[-5:] == 'color' and len(args):
     491        #    args = (get_colour(args[0]),)
     492
     493        newargs = {}
     494        for k, v in kwargs.iteritems():
     495            k = k.lower()
     496            if k == 'colour': k = 'color'
     497            newargs[k] = v
     498
     499        getattr(self.figure, "set_%s"%what)(*args, **newargs)
     500        self.show()
    481501
    482502
    483503    def set_limits(self, xlim=None, ylim=None):
    484         """
    485         Set x-, and y-limits for each subplot.
    486 
    487         xlim = [xmin, xmax] as in axes.set_xlim().
    488         ylim = [ymin, ymax] as in axes.set_ylim().
    489         """
    490         for s in self.subplots:
    491             self.axes  = s['axes']
    492             self.lines = s['lines']
     504        """
     505        Set x-, and y-limits for each subplot.
     506
     507        xlim = [xmin, xmax] as in axes.set_xlim().
     508        ylim = [ymin, ymax] as in axes.set_ylim().
     509        """
     510        for s in self.subplots:
     511            self.axes  = s['axes']
     512            self.lines = s['lines']
    493513            oldxlim =  list(self.axes.get_xlim())
    494514            oldylim =  list(self.axes.get_ylim())
     
    497517                    if xlim[i] is not None:
    498518                        oldxlim[i] = xlim[i]
    499             if ylim is not None:                       
     519            if ylim is not None:
    500520                for i in range(len(ylim)):
    501521                    if ylim[i] is not None:
     
    507527
    508528    def set_line(self, number=None, **kwargs):
    509         """
    510         Set attributes for the specified line, or else the next line(s)
    511         to be plotted.
    512 
    513         number is the 0-relative number of a line that has already been
    514         plotted.  If no such line exists, attributes are recorded and used
    515         for the next line(s) to be plotted.
    516 
    517         Keyword arguments specify Line2D attributes, e.g. color='r'.  Do
    518 
    519             import matplotlib
    520             help(matplotlib.lines)
    521 
    522         The set_* methods of class Line2D define the attribute names and
    523         values.  For non-US usage, "colour" is recognized as synonymous with
    524         "color".
    525 
    526         Set the value to None to delete an attribute.
    527 
    528         Colour translation is done as described in the doctext for palette().
    529         """
    530 
    531         redraw = False
    532         for k, v in kwargs.iteritems():
    533             k = k.lower()
    534             if k == 'colour': k = 'color'
    535 
    536             if 0 <= number < len(self.lines):
    537                 if self.lines[number] is not None:
    538                     for line in self.lines[number]:
    539                         getattr(line, "set_%s"%k)(v)
    540                     redraw = True
    541             else:
    542                 if v is None:
    543                     del self.attributes[k]
    544                 else:
    545                     self.attributes[k] = v
    546 
    547         if redraw: self.show()
     529        """
     530        Set attributes for the specified line, or else the next line(s)
     531        to be plotted.
     532
     533        number is the 0-relative number of a line that has already been
     534        plotted.  If no such line exists, attributes are recorded and used
     535        for the next line(s) to be plotted.
     536
     537        Keyword arguments specify Line2D attributes, e.g. color='r'.  Do
     538
     539            import matplotlib
     540            help(matplotlib.lines)
     541
     542        The set_* methods of class Line2D define the attribute names and
     543        values.  For non-US usage, "colour" is recognized as synonymous with
     544        "color".
     545
     546        Set the value to None to delete an attribute.
     547
     548        Colour translation is done as described in the doctext for palette().
     549        """
     550
     551        redraw = False
     552        for k, v in kwargs.iteritems():
     553            k = k.lower()
     554            if k == 'colour': k = 'color'
     555
     556            if 0 <= number < len(self.lines):
     557                if self.lines[number] is not None:
     558                    for line in self.lines[number]:
     559                        getattr(line, "set_%s"%k)(v)
     560                    redraw = True
     561            else:
     562                if v is None:
     563                    del self.attributes[k]
     564                else:
     565                    self.attributes[k] = v
     566
     567        if redraw: self.show()
    548568
    549569
    550570    def set_panels(self, rows=1, cols=0, n=-1, nplots=-1, ganged=True):
    551         """
    552         Set the panel layout.
    553 
    554         rows and cols, if cols != 0, specify the number of rows and columns in
    555         a regular layout.   (Indexing of these panels in matplotlib is row-
    556         major, i.e. column varies fastest.)
    557 
    558         cols == 0 is interpreted as a retangular layout that accomodates
    559         'rows' panels, e.g. rows == 6, cols == 0 is equivalent to
    560         rows == 2, cols == 3.
    561 
    562         0 <= n < rows*cols is interpreted as the 0-relative panel number in
    563         the configuration specified by rows and cols to be added to the
    564         current figure as its next 0-relative panel number (i).  This allows
    565         non-regular panel layouts to be constructed via multiple calls.  Any
    566         other value of n clears the plot and produces a rectangular array of
    567         empty panels.  The number of these may be limited by nplots.
    568         """
    569         if n < 0 and len(self.subplots):
    570             self.figure.clear()
    571             self.set_title()
    572 
    573         if rows < 1: rows = 1
    574 
    575         if cols <= 0:
    576             i = int(sqrt(rows))
    577             if i*i < rows: i += 1
    578             cols = i
    579 
    580             if i*(i-1) >= rows: i -= 1
    581             rows = i
    582 
    583         if 0 <= n < rows*cols:
    584             i = len(self.subplots)
    585             self.subplots.append({})
    586 
    587             self.subplots[i]['axes']  = self.figure.add_subplot(rows,
    588                                             cols, n+1)
    589             self.subplots[i]['lines'] = []
    590 
    591             if i == 0: self.subplot(0)
    592 
    593             self.rows = 0
    594             self.cols = 0
    595 
    596         else:
    597             self.subplots = []
    598 
    599             if nplots < 1 or rows*cols < nplots:
    600                 nplots = rows*cols
    601 
    602             for i in range(nplots):
    603                 self.subplots.append({})
    604 
    605                 self.subplots[i]['axes']  = self.figure.add_subplot(rows,
    606                                                 cols, i+1)
    607                 self.subplots[i]['lines'] = []
    608                 xfsize = self.subplots[i]['axes'].xaxis.label.get_size()-cols/2
    609                 yfsize = self.subplots[i]['axes'].yaxis.label.get_size()-rows/2
    610                 self.subplots[i]['axes'].xaxis.label.set_size(xfsize)
    611                 self.subplots[i]['axes'].yaxis.label.set_size(yfsize)
    612                
     571        """
     572        Set the panel layout.
     573
     574        rows and cols, if cols != 0, specify the number of rows and columns in
     575        a regular layout.   (Indexing of these panels in matplotlib is row-
     576        major, i.e. column varies fastest.)
     577
     578        cols == 0 is interpreted as a retangular layout that accomodates
     579        'rows' panels, e.g. rows == 6, cols == 0 is equivalent to
     580        rows == 2, cols == 3.
     581
     582        0 <= n < rows*cols is interpreted as the 0-relative panel number in
     583        the configuration specified by rows and cols to be added to the
     584        current figure as its next 0-relative panel number (i).  This allows
     585        non-regular panel layouts to be constructed via multiple calls.  Any
     586        other value of n clears the plot and produces a rectangular array of
     587        empty panels.  The number of these may be limited by nplots.
     588        """
     589        if n < 0 and len(self.subplots):
     590            self.figure.clear()
     591            self.set_title()
     592
     593        if rows < 1: rows = 1
     594
     595        if cols <= 0:
     596            i = int(sqrt(rows))
     597            if i*i < rows: i += 1
     598            cols = i
     599
     600            if i*(i-1) >= rows: i -= 1
     601            rows = i
     602
     603        if 0 <= n < rows*cols:
     604            i = len(self.subplots)
     605            self.subplots.append({})
     606
     607            self.subplots[i]['axes']  = self.figure.add_subplot(rows,
     608                                            cols, n+1)
     609            self.subplots[i]['lines'] = []
     610
     611            if i == 0: self.subplot(0)
     612
     613            self.rows = 0
     614            self.cols = 0
     615
     616        else:
     617            self.subplots = []
     618
     619            if nplots < 1 or rows*cols < nplots:
     620                nplots = rows*cols
     621
     622            for i in range(nplots):
     623                self.subplots.append({})
     624
     625                self.subplots[i]['axes']  = self.figure.add_subplot(rows,
     626                                                cols, i+1)
     627                self.subplots[i]['lines'] = []
     628
    613629                if ganged:
    614630                    if rows > 1 or cols > 1:
     
    624640                            # Suppress x-labels for frames width
    625641                            # adjacent frames
    626                             for tick in \
    627                                     self.subplots[i]['axes'].xaxis.majorTicks:
    628                                 tick.label1On = False
    629                                 self.subplots[i]['axes'].xaxis.label.set_visible(False)
     642                            self.subplots[i]['axes'].xaxis.set_major_locator(NullLocator())
     643                            self.subplots[i]['axes'].xaxis.label.set_visible(False)
    630644                    if i%cols:
    631645                        # Suppress y-labels for frames not in the left column.
     
    633647                            tick.label1On = False
    634648                        self.subplots[i]['axes'].yaxis.label.set_visible(False)
    635                        
    636 
    637                 self.rows = rows
    638                 self.cols = cols
    639 
    640             self.subplot(0)
     649                    if (i+1)%cols:
     650                        self.subplots[i]['axes'].xaxis.set_major_formatter(MyFormatter())
     651                self.rows = rows
     652                self.cols = cols
     653
     654            self.subplot(0)
    641655
    642656    def set_title(self, title=None):
    643         """
    644         Set the title of the plot window.  Use the previous title if title is
    645         omitted.
    646         """
    647         if title is not None:
    648             self.title = title
    649 
    650         self.figure.text(0.5, 0.95, self.title, horizontalalignment='center')
     657        """
     658        Set the title of the plot window.  Use the previous title if title is
     659        omitted.
     660        """
     661        if title is not None:
     662            self.title = title
     663
     664        self.figure.text(0.5, 0.95, self.title, horizontalalignment='center')
    651665
    652666
    653667    def show(self):
    654         """
    655         Show graphics dependent on the current buffering state.
    656         """
    657         if not self.buffering:
    658             if self.loc is not None:
    659                 for j in range(len(self.subplots)):
    660                     lines  = []
    661                     labels = []
    662                     i = 0
    663                     for line in self.subplots[j]['lines']:
    664                         i += 1
    665                         if line is not None:
    666                             lines.append(line[0])
    667                             lbl = line[0].get_label()
    668                             if lbl == '':
    669                                 lbl = str(i)
    670                             labels.append(lbl)
    671 
    672                     if len(lines):
    673                         self.subplots[j]['axes'].legend(tuple(lines),
    674                                                         tuple(labels),
    675                                                         self.loc)
    676                     else:
    677                         self.subplots[j]['axes'].legend((' '))
     668        """
     669        Show graphics dependent on the current buffering state.
     670        """
     671        if not self.buffering:
     672            if self.loc is not None:
     673                for j in range(len(self.subplots)):
     674                    lines  = []
     675                    labels = []
     676                    i = 0
     677                    for line in self.subplots[j]['lines']:
     678                        i += 1
     679                        if line is not None:
     680                            lines.append(line[0])
     681                            lbl = line[0].get_label()
     682                            if lbl == '':
     683                                lbl = str(i)
     684                            labels.append(lbl)
     685
     686                    if len(lines):
     687                        self.subplots[j]['axes'].legend(tuple(lines),
     688                                                        tuple(labels),
     689                                                        self.loc)
     690                    else:
     691                        self.subplots[j]['axes'].legend((' '))
    678692
    679693
    680694    def subplot(self, i=None, inc=None):
    681         """
    682         Set the subplot to the 0-relative panel number as defined by one or
    683         more invokations of set_panels().
    684         """
    685         l = len(self.subplots)
    686         if l:
    687             if i is not None:
    688                 self.i = i
    689 
    690             if inc is not None:
    691                 self.i += inc
    692 
    693             self.i %= l
    694             self.axes  = self.subplots[self.i]['axes']
    695             self.lines = self.subplots[self.i]['lines']
     695        """
     696        Set the subplot to the 0-relative panel number as defined by one or
     697        more invokations of set_panels().
     698        """
     699        l = len(self.subplots)
     700        if l:
     701            if i is not None:
     702                self.i = i
     703
     704            if inc is not None:
     705                self.i += inc
     706
     707            self.i %= l
     708            self.axes  = self.subplots[self.i]['axes']
     709            self.lines = self.subplots[self.i]['lines']
    696710
    697711
    698712    def text(self, *args, **kwargs):
    699         """
    700         Add text to the figure.
    701         """
    702         self.figure.text(*args, **kwargs)
    703         self.show()
     713        """
     714        Add text to the figure.
     715        """
     716        self.figure.text(*args, **kwargs)
     717        self.show()
Note: See TracChangeset for help on using the changeset viewer.