casa  $Rev:20696$
 All Classes Namespaces Files Functions Variables
asaplotbase.py
Go to the documentation of this file.
00001 """
00002 ASAP plotting class based on matplotlib.
00003 """
00004 
00005 import sys
00006 from re import match
00007 import matplotlib
00008 
00009 from matplotlib.figure import Figure, Text
00010 from matplotlib.font_manager import FontProperties as FP
00011 from numpy import sqrt
00012 from matplotlib import rc, rcParams
00013 from matplotlib.ticker import OldScalarFormatter
00014 from matplotlib import _pylab_helpers
00015 
00016 from asap.parameters import rcParams as asaprcParams
00017 from asap.logging import asaplog
00018 
00019 # API change in mpl >= 0.98
00020 try:
00021     from matplotlib.transforms import blended_transform_factory
00022 except ImportError:
00023     from matplotlib.transforms import blend_xy_sep_transform as blended_transform_factory
00024 
00025 mvers = matplotlib.__version__.split(".")
00026 if int(mvers[0]) == 0 and int(mvers[1]) < 99:
00027     #print "Warning: matplotlib version < 0.87. This might cause errors. Please upgrade."
00028     asaplog.push( "matplotlib version < 0.99. This might cause errors. Please upgrade." )
00029     asaplog.post( 'WARN' )
00030 
00031 class asaplotbase:
00032     """
00033     ASAP plotting base class based on matplotlib.
00034     """
00035 
00036     def __init__(self, rows=1, cols=0, title='', size=None, buffering=False):
00037         """
00038         Create a new instance of the ASAPlot plotting class.
00039 
00040         If rows < 1 then a separate call to set_panels() is required to define
00041         the panel layout; refer to the doctext for set_panels().
00042         """
00043         self.is_dead = False
00044         self.figure = Figure(figsize=size, facecolor='#ddddee')
00045         self.canvas = None
00046 
00047         self.set_title(title)
00048         self.subplots = []
00049         if rows > 0:
00050             self.set_panels(rows, cols)
00051 
00052         # Set matplotlib default colour sequence.
00053         self.colormap = "green red black cyan magenta orange blue purple yellow pink".split()
00054 
00055         c = asaprcParams['plotter.colours']
00056         if isinstance(c,str) and len(c) > 0:
00057             self.colormap = c.split()
00058 
00059         self.lsalias = {"line":  [1,0],
00060                         "dashdot": [4,2,1,2],
00061                         "dashed" : [4,2,4,2],
00062                         "dotted" : [1,2],
00063                         "dashdotdot": [4,2,1,2,1,2],
00064                         "dashdashdot": [4,2,4,2,1,2]
00065                         }
00066 
00067         styles = "line dashed dotted dashdot".split()
00068         c = asaprcParams['plotter.linestyles']
00069         if isinstance(c,str) and len(c) > 0:
00070             styles = c.split()
00071         s = []
00072         for ls in styles:
00073             if self.lsalias.has_key(ls):
00074                 s.append(self.lsalias.get(ls))
00075             else:
00076                 s.append('-')
00077         self.linestyles = s
00078 
00079         self.color = 0;
00080         self.linestyle = 0;
00081         self.attributes = {}
00082         self.loc = 0
00083 
00084         self.buffering = buffering
00085 
00086         self.events = {'button_press':None,
00087                        'button_release':None,
00088                        'motion_notify':None}
00089 
00090     def clear(self):
00091         """
00092         Delete all lines from the plot.  Line numbering will restart from 0.
00093         """
00094 
00095         for i in range(len(self.lines)):
00096            self.delete(i)
00097         self.axes.clear()
00098         self.color = 0
00099         self.lines = []
00100 
00101     def palette(self, color, colormap=None, linestyle=0, linestyles=None):
00102         if colormap:
00103             if isinstance(colormap,list):
00104                 self.colormap = colormap
00105             elif isinstance(colormap,str):
00106                 self.colormap = colormap.split()
00107         if 0 <= color < len(self.colormap):
00108             self.color = color
00109         if linestyles:
00110             self.linestyles = []
00111             if isinstance(linestyles,list):
00112                 styles = linestyles
00113             elif isinstance(linestyles,str):
00114                 styles = linestyles.split()
00115             for ls in styles:
00116                 if self.lsalias.has_key(ls):
00117                     self.linestyles.append(self.lsalias.get(ls))
00118                 else:
00119                     self.linestyles.append(self.lsalias.get('line'))
00120         if 0 <= linestyle < len(self.linestyles):
00121             self.linestyle = linestyle
00122 
00123     def delete(self, numbers=None):
00124         """
00125         Delete the 0-relative line number, default is to delete the last.
00126         The remaining lines are NOT renumbered.
00127         """
00128 
00129         if numbers is None: numbers = [len(self.lines)-1]
00130 
00131         if not hasattr(numbers, '__iter__'):
00132             numbers = [numbers]
00133 
00134         for number in numbers:
00135             if 0 <= number < len(self.lines):
00136                 if self.lines[number] is not None:
00137                     for line in self.lines[number]:
00138                         line.set_linestyle('None')
00139                         self.lines[number] = None
00140         self.show()
00141 
00142     def get_line(self):
00143         """
00144         Get the current default line attributes.
00145         """
00146         return self.attributes
00147 
00148 
00149     def hist(self, x=None, y=None, fmt=None, add=None):
00150         """
00151         Plot a histogram.  N.B. the x values refer to the start of the
00152         histogram bin.
00153 
00154         fmt is the line style as in plot().
00155         """
00156         from numpy import array
00157         from numpy.ma import MaskedArray
00158         if x is None:
00159             if y is None: return
00160             x = range(len(y))
00161 
00162         if len(x) != len(y):
00163             return
00164         l2 = 2*len(x)
00165         x2 = range(l2)
00166         y2 = range(12)
00167         y2 = range(l2)
00168         m2 = range(l2)
00169         ymsk = None
00170         ydat = None
00171         if hasattr(y, "raw_mask"):
00172             # numpy < 1.1
00173             ymsk = y.raw_mask()
00174             ydat = y.raw_data()
00175         else:
00176             ymsk = y.mask
00177             ydat = y.data
00178         for i in range(l2):
00179             x2[i] = x[i/2]
00180             m2[i] = ymsk[i/2]
00181 
00182         y2[0] = 0.0
00183         for i in range(1,l2):
00184             y2[i] = ydat[(i-1)/2]
00185 
00186         self.plot(x2, MaskedArray(y2,mask=m2,copy=0), fmt, add)
00187 
00188 
00189     def hold(self, hold=True):
00190         """
00191         Buffer graphics until subsequently released.
00192         """
00193         self.buffering = hold
00194 
00195 
00196     def legend(self, loc=None):
00197         """
00198         Add a legend to the plot.
00199 
00200         Any other value for loc else disables the legend:
00201              1: upper right
00202              2: upper left
00203              3: lower left
00204              4: lower right
00205              5: right
00206              6: center left
00207              7: center right
00208              8: lower center
00209              9: upper center
00210             10: center
00211 
00212         """
00213         if isinstance(loc, int):
00214             self.loc = None
00215             if 0 <= loc <= 10: self.loc = loc
00216         else:
00217             self.loc = None
00218         #self.show()
00219 
00220 
00221     def plot(self, x=None, y=None, fmt=None, add=None):
00222         """
00223         Plot the next line in the current frame using the current line
00224         attributes.  The ASAPlot graphics window will be mapped and raised.
00225 
00226         The argument list works a bit like the matlab plot() function.
00227         """
00228         if x is None:
00229             if y is None: return
00230             x = range(len(y))
00231 
00232         elif y is None:
00233             y = x
00234             x = range(len(y))
00235         if fmt is None:
00236             line = self.axes.plot(x, y)
00237         else:
00238             line = self.axes.plot(x, y, fmt)
00239         # add a picker to lines for spectral value mode.
00240         # matplotlib.axes.plot returns a list of line object (1 element)
00241         line[0].set_picker(5.0)
00242 
00243         # Add to an existing line?
00244         i = None
00245         if add is None or len(self.lines) < add < 0:
00246             # Don't add.
00247             self.lines.append(line)
00248             i = len(self.lines) - 1
00249         else:
00250             if add == 0: add = len(self.lines)
00251             i = add - 1
00252             self.lines[i].extend(line)
00253 
00254         # Set/reset attributes for the line.
00255         gotcolour = False
00256         for k, v in self.attributes.iteritems():
00257             if k == 'color': gotcolour = True
00258             for segment in self.lines[i]:
00259                 getattr(segment, "set_%s"%k)(v)
00260 
00261         if not gotcolour and len(self.colormap):
00262             for segment in self.lines[i]:
00263                 getattr(segment, "set_color")(self.colormap[self.color])
00264                 if len(self.colormap)  == 1:
00265                     getattr(segment, "set_dashes")(self.linestyles[self.linestyle])
00266 
00267             self.color += 1
00268             if self.color >= len(self.colormap):
00269                 self.color = 0
00270 
00271             if len(self.colormap) == 1:
00272                 self.linestyle += 1
00273             if self.linestyle >= len(self.linestyles):
00274                 self.linestyle = 0
00275 
00276         self.show()
00277 
00278 
00279     def position(self):
00280         """
00281         Use the mouse to get a position from a graph.
00282         """
00283 
00284         def position_disable(event):
00285             self.register('button_press', None)
00286             print '%.4f, %.4f' % (event.xdata, event.ydata)
00287 
00288         print 'Press any mouse button...'
00289         self.register('button_press', position_disable)
00290 
00291 
00292     def get_region(self):
00293         pos = []
00294         print "Please select the bottom/left point"
00295         pos.append(self.figure.ginput(n=1, show_clicks=False)[0])
00296         print "Please select the top/right point"
00297         pos.append(self.figure.ginput(n=1, show_clicks=False)[0])
00298         return pos
00299 
00300     def get_point(self):
00301         print "Please select the point"
00302         pt = self.figure.ginput(n=1, show_clicks=False)
00303         if pt:
00304             return pt[0]
00305         else:
00306             return None
00307 
00308     def region(self):
00309         """
00310         Use the mouse to get a rectangular region from a plot.
00311 
00312         The return value is [x0, y0, x1, y1] in world coordinates.
00313         """
00314 
00315         def region_start(event):
00316             self.rect = {'x': event.x, 'y': event.y,
00317                          'world': [event.xdata, event.ydata,
00318                                    event.xdata, event.ydata]}
00319             self.register('button_press', None)
00320             self.register('motion_notify', region_draw)
00321             self.register('button_release', region_disable)
00322 
00323         def region_draw(event):
00324             self.figmgr.toolbar.draw_rubberband(event, event.x, event.y,
00325                                                 self.rect['x'], self.rect['y'])
00326 
00327         def region_disable(event):
00328             self.register('motion_notify', None)
00329             self.register('button_release', None)
00330 
00331             self.rect['world'][2:4] = [event.xdata, event.ydata]
00332             print '(%.2f, %.2f)  (%.2f, %.2f)' % (self.rect['world'][0],
00333                 self.rect['world'][1], self.rect['world'][2],
00334                 self.rect['world'][3])
00335             self.figmgr.toolbar.release(event)
00336 
00337         self.register('button_press', region_start)
00338 
00339         # This has to be modified to block and return the result (currently
00340         # printed by region_disable) when that becomes possible in matplotlib.
00341 
00342         return [0.0, 0.0, 0.0, 0.0]
00343 
00344 
00345     def register(self, type=None, func=None):
00346         """
00347         Register, reregister, or deregister events of type 'button_press',
00348         'button_release', or 'motion_notify'.
00349 
00350         The specified callback function should have the following signature:
00351 
00352             def func(event)
00353 
00354         where event is an MplEvent instance containing the following data:
00355 
00356             name                # Event name.
00357             canvas              # FigureCanvas instance generating the event.
00358             x      = None       # x position - pixels from left of canvas.
00359             y      = None       # y position - pixels from bottom of canvas.
00360             button = None       # Button pressed: None, 1, 2, 3.
00361             key    = None       # Key pressed: None, chr(range(255)), shift,
00362                                   win, or control
00363             inaxes = None       # Axes instance if cursor within axes.
00364             xdata  = None       # x world coordinate.
00365             ydata  = None       # y world coordinate.
00366 
00367         For example:
00368 
00369             def mouse_move(event):
00370                 print event.xdata, event.ydata
00371 
00372             a = asaplot()
00373             a.register('motion_notify', mouse_move)
00374 
00375         If func is None, the event is deregistered.
00376 
00377         Note that in TkAgg keyboard button presses don't generate an event.
00378         """
00379 
00380         if not self.events.has_key(type): return
00381 
00382         if func is None:
00383             if self.events[type] is not None:
00384                 # It's not clear that this does anything.
00385                 self.canvas.mpl_disconnect(self.events[type])
00386                 self.events[type] = None
00387 
00388                 # It seems to be necessary to return events to the toolbar. <-- Not ture. 2010.Jul.14.kana.
00389                 #if type == 'motion_notify':
00390                 #    self.canvas.mpl_connect(type + '_event',
00391                 #        self.figmgr.toolbar.mouse_move)
00392                 #elif type == 'button_press':
00393                 #    self.canvas.mpl_connect(type + '_event',
00394                 #        self.figmgr.toolbar.press)
00395                 #elif type == 'button_release':
00396                 #    self.canvas.mpl_connect(type + '_event',
00397                 #        self.figmgr.toolbar.release)
00398 
00399         else:
00400             self.events[type] = self.canvas.mpl_connect(type + '_event', func)
00401 
00402 
00403     def release(self):
00404         """
00405         Release buffered graphics.
00406         """
00407         self.buffering = False
00408         self.show()
00409 
00410 
00411     def save(self, fname=None, orientation=None, dpi=None, papertype=None):
00412         """
00413         Save the plot to a file.
00414 
00415         fname is the name of the output file.  The image format is determined
00416         from the file suffix; 'png', 'ps', and 'eps' are recognized.  If no
00417         file name is specified 'yyyymmdd_hhmmss.png' is created in the current
00418         directory.
00419         """
00420         from asap import rcParams
00421         if papertype is None:
00422             papertype = rcParams['plotter.papertype']
00423         if fname is None:
00424             from datetime import datetime
00425             dstr = datetime.now().strftime('%Y%m%d_%H%M%S')
00426             fname = 'asap'+dstr+'.png'
00427 
00428         d = ['png','.ps','eps', 'svg']
00429 
00430         from os.path import expandvars
00431         fname = expandvars(fname)
00432 
00433         if fname[-3:].lower() in d:
00434             try:
00435                 if fname[-3:].lower() == ".ps":
00436                     from matplotlib import __version__ as mv
00437                     w = self.figure.get_figwidth()
00438                     h = self.figure.get_figheight()
00439 
00440                     if orientation is None:
00441                         # oriented
00442                         if w > h:
00443                             orientation = 'landscape'
00444                         else:
00445                             orientation = 'portrait'
00446                     from matplotlib.backends.backend_ps import papersize
00447                     pw,ph = papersize[papertype.lower()]
00448                     ds = None
00449                     if orientation == 'landscape':
00450                         ds = min(ph/w, pw/h)
00451                     else:
00452                         ds = min(pw/w, ph/h)
00453                     ow = ds * w
00454                     oh = ds * h
00455                     self.figure.set_size_inches((ow, oh))
00456                     self.figure.savefig(fname, orientation=orientation,
00457                                         papertype=papertype.lower())
00458                     self.figure.set_size_inches((w, h))
00459                     print 'Written file %s' % (fname)
00460                 else:
00461                     if dpi is None:
00462                         dpi =150
00463                     self.figure.savefig(fname,dpi=dpi)
00464                     print 'Written file %s' % (fname)
00465             except IOError, msg:
00466                 #print 'Failed to save %s: Error msg was\n\n%s' % (fname, err)
00467                 asaplog.post()
00468                 asaplog.push('Failed to save %s: Error msg was\n\n%s' % (fname, str(msg)))
00469                 asaplog.post( 'ERROR' )
00470                 return
00471         else:
00472             #print "Invalid image type. Valid types are:"
00473             #print "'ps', 'eps', 'png'"
00474             asaplog.push( "Invalid image type. Valid types are:" )
00475             asaplog.push( "'ps', 'eps', 'png', 'svg'" )
00476             asaplog.post('WARN')
00477 
00478 
00479     def set_axes(self, what=None, *args, **kwargs):
00480         """
00481         Set attributes for the axes by calling the relevant Axes.set_*()
00482         method.  Colour translation is done as described in the doctext
00483         for palette().
00484         """
00485 
00486         if what is None: return
00487         if what[-6:] == 'colour': what = what[:-6] + 'color'
00488 
00489         key = "colour"
00490         if kwargs.has_key(key):
00491             val = kwargs.pop(key)
00492             kwargs["color"] = val
00493 
00494         getattr(self.axes, "set_%s"%what)(*args, **kwargs)
00495 
00496         self.show(hardrefresh=False)
00497 
00498 
00499     def set_figure(self, what=None, *args, **kwargs):
00500         """
00501         Set attributes for the figure by calling the relevant Figure.set_*()
00502         method.  Colour translation is done as described in the doctext
00503         for palette().
00504         """
00505 
00506         if what is None: return
00507         if what[-6:] == 'colour': what = what[:-6] + 'color'
00508         #if what[-5:] == 'color' and len(args):
00509         #    args = (get_colour(args[0]),)
00510 
00511         newargs = {}
00512         for k, v in kwargs.iteritems():
00513             k = k.lower()
00514             if k == 'colour': k = 'color'
00515             newargs[k] = v
00516 
00517         getattr(self.figure, "set_%s"%what)(*args, **newargs)
00518         self.show(hardrefresh=False)
00519 
00520 
00521     def set_limits(self, xlim=None, ylim=None):
00522         """
00523         Set x-, and y-limits for each subplot.
00524 
00525         xlim = [xmin, xmax] as in axes.set_xlim().
00526         ylim = [ymin, ymax] as in axes.set_ylim().
00527         """
00528         for s in self.subplots:
00529             self.axes  = s['axes']
00530             self.lines = s['lines']
00531             oldxlim =  list(self.axes.get_xlim())
00532             oldylim =  list(self.axes.get_ylim())
00533             if xlim is not None:
00534                 for i in range(len(xlim)):
00535                     if xlim[i] is not None:
00536                         oldxlim[i] = xlim[i]
00537             if ylim is not None:
00538                 for i in range(len(ylim)):
00539                     if ylim[i] is not None:
00540                         oldylim[i] = ylim[i]
00541             self.axes.set_xlim(oldxlim)
00542             self.axes.set_ylim(oldylim)
00543         return
00544 
00545 
00546     def set_line(self, number=None, **kwargs):
00547         """
00548         Set attributes for the specified line, or else the next line(s)
00549         to be plotted.
00550 
00551         number is the 0-relative number of a line that has already been
00552         plotted.  If no such line exists, attributes are recorded and used
00553         for the next line(s) to be plotted.
00554 
00555         Keyword arguments specify Line2D attributes, e.g. color='r'.  Do
00556 
00557             import matplotlib
00558             help(matplotlib.lines)
00559 
00560         The set_* methods of class Line2D define the attribute names and
00561         values.  For non-US usage, 'colour' is recognized as synonymous with
00562         'color'.
00563 
00564         Set the value to None to delete an attribute.
00565 
00566         Colour translation is done as described in the doctext for palette().
00567         """
00568 
00569         redraw = False
00570         for k, v in kwargs.iteritems():
00571             k = k.lower()
00572             if k == 'colour': k = 'color'
00573 
00574             if 0 <= number < len(self.lines):
00575                 if self.lines[number] is not None:
00576                     for line in self.lines[number]:
00577                         getattr(line, "set_%s"%k)(v)
00578                     redraw = True
00579             else:
00580                 if v is None:
00581                     del self.attributes[k]
00582                 else:
00583                     self.attributes[k] = v
00584 
00585         if redraw: self.show(hardrefresh=False)
00586 
00587 
00588     #def set_panels(self, rows=1, cols=0, n=-1, nplots=-1, ganged=True):
00589     def set_panels(self, rows=1, cols=0, n=-1, nplots=-1, margin=None,ganged=True):
00590         """
00591         Set the panel layout.
00592 
00593         rows and cols, if cols != 0, specify the number of rows and columns in
00594         a regular layout.   (Indexing of these panels in matplotlib is row-
00595         major, i.e. column varies fastest.)
00596 
00597         cols == 0 is interpreted as a retangular layout that accomodates
00598         'rows' panels, e.g. rows == 6, cols == 0 is equivalent to
00599         rows == 2, cols == 3.
00600 
00601         0 <= n < rows*cols is interpreted as the 0-relative panel number in
00602         the configuration specified by rows and cols to be added to the
00603         current figure as its next 0-relative panel number (i).  This allows
00604         non-regular panel layouts to be constructed via multiple calls.  Any
00605         other value of n clears the plot and produces a rectangular array of
00606         empty panels.  The number of these may be limited by nplots.
00607         """
00608         if n < 0 and len(self.subplots):
00609             self.figure.clear()
00610             self.set_title()
00611 
00612         if margin:
00613             lef, bot, rig, top, wsp, hsp = margin
00614             self.figure.subplots_adjust(
00615                 left=lef,bottom=bot,right=rig,top=top,wspace=wsp,hspace=hsp)
00616             del lef,bot,rig,top,wsp,hsp
00617 
00618         if rows < 1: rows = 1
00619 
00620         if cols <= 0:
00621             i = int(sqrt(rows))
00622             if i*i < rows: i += 1
00623             cols = i
00624 
00625             if i*(i-1) >= rows: i -= 1
00626             rows = i
00627 
00628         if 0 <= n < rows*cols:
00629             i = len(self.subplots)
00630 
00631             self.subplots.append({})
00632 
00633             self.subplots[i]['axes']  = self.figure.add_subplot(rows,
00634                                             cols, n+1)
00635             self.subplots[i]['lines'] = []
00636 
00637             if i == 0: self.subplot(0)
00638 
00639             self.rows = 0
00640             self.cols = 0
00641 
00642         else:
00643             self.subplots = []
00644 
00645             if nplots < 1 or rows*cols < nplots:
00646                 nplots = rows*cols
00647             if ganged:
00648                 hsp,wsp = None,None
00649                 if rows > 1: hsp = 0.0001
00650                 if cols > 1: wsp = 0.0001
00651                 self.figure.subplots_adjust(wspace=wsp,hspace=hsp)
00652             for i in range(nplots):
00653                 self.subplots.append({})
00654                 self.subplots[i]['lines'] = []
00655                 if not ganged:
00656                     self.subplots[i]['axes'] = self.figure.add_subplot(rows,
00657                                                 cols, i+1)
00658                     if asaprcParams['plotter.axesformatting'] != 'mpl':
00659                         self.subplots[i]['axes'].xaxis.set_major_formatter(OldScalarFormatter())
00660                 else:
00661                     if i == 0:
00662                         self.subplots[i]['axes'] = self.figure.add_subplot(rows,
00663                                                 cols, i+1)
00664                         if asaprcParams['plotter.axesformatting'] != 'mpl':
00665 
00666                             self.subplots[i]['axes'].xaxis.set_major_formatter(OldScalarFormatter())
00667                     else:
00668                         self.subplots[i]['axes'] = self.figure.add_subplot(rows,
00669                                                 cols, i+1,
00670                                                 sharex=self.subplots[0]['axes'],
00671                                                 sharey=self.subplots[0]['axes'])
00672 
00673                     # Suppress tick labelling for interior subplots.
00674                     if i <= (rows-1)*cols - 1:
00675                         if i+cols < nplots:
00676                             # Suppress x-labels for frames width
00677                             # adjacent frames
00678                             for tick in self.subplots[i]['axes'].xaxis.majorTicks:
00679                                 tick.label1On = False
00680                             #self.subplots[i]['axes'].xaxis.label.set_visible(False)
00681                     if i%cols:
00682                         # Suppress y-labels for frames not in the left column.
00683                         for tick in self.subplots[i]['axes'].yaxis.majorTicks:
00684                             tick.label1On = False
00685                         #self.subplots[i]['axes'].yaxis.label.set_visible(False)
00686                     # disable the first tick of [1:ncol-1] of the last row
00687                     #if i+1 < nplots:
00688                     #    self.subplots[i]['axes'].xaxis.majorTicks[0].label1On = False
00689                 # set axes label state for interior subplots.
00690                 if i%cols:
00691                     self.subplots[i]['axes'].yaxis.label.set_visible(False)
00692                 if (i <= (rows-1)*cols - 1) and (i+cols < nplots):
00693                     self.subplots[i]['axes'].xaxis.label.set_visible(False)
00694             self.rows = rows
00695             self.cols = cols
00696             self.subplot(0)
00697         del rows,cols,n,nplots,margin,ganged,i
00698 
00699 
00700     def tidy(self):
00701         # this needs to be exceuted after the first "refresh"
00702         nplots = len(self.subplots)
00703         if nplots == 1: return
00704         for i in xrange(nplots):
00705             ax = self.subplots[i]['axes']
00706             if i%self.cols:
00707                 ax.xaxis.majorTicks[0].label1On = False
00708             else:
00709                 if i != 0:
00710                     ax.yaxis.majorTicks[-1].label1On = False
00711             ## set axes label state for interior subplots.
00712             #innerax=False
00713             #if i%self.cols:
00714             #    ax.yaxis.label.set_visible(innerax)
00715             #if (i <= (self.rows-1)*self.cols - 1) and (i+self.cols < nplots):
00716             #    ax.xaxis.label.set_visible(innerax)
00717             
00718 
00719     def set_title(self, title=None):
00720         """
00721         Set the title of the plot window.  Use the previous title if title is
00722         omitted.
00723         """
00724         if title is not None:
00725             self.title = title
00726 
00727         self.figure.text(0.5, 0.95, self.title, horizontalalignment='center')
00728 
00729 
00730     def show(self, hardrefresh=True):
00731         """
00732         Show graphics dependent on the current buffering state.
00733         """
00734         if not hardrefresh: return
00735         if not self.buffering:
00736             if self.loc is not None:
00737                 for sp in self.subplots:
00738                     lines  = []
00739                     labels = []
00740                     i = 0
00741                     for line in sp['lines']:
00742                         i += 1
00743                         if line is not None:
00744                             lines.append(line[0])
00745                             lbl = line[0].get_label()
00746                             if lbl == '':
00747                                 lbl = str(i)
00748                             labels.append(lbl)
00749 
00750                     if len(lines):
00751                         fp = FP(size=rcParams['legend.fontsize'])
00752                         #fsz = fp.get_size_in_points() - len(lines)
00753                         fsz = fp.get_size_in_points() - max(len(lines),self.cols)
00754                         #fp.set_size(max(fsz,6))
00755                         fp.set_size(max(fsz,8))
00756                         sp['axes'].legend(tuple(lines), tuple(labels),
00757                                           self.loc, prop=fp)
00758                     #else:
00759                     #    sp['axes'].legend((' '))
00760 
00761             from matplotlib.artist import setp
00762             fpx = FP(size=rcParams['xtick.labelsize'])
00763             xts = fpx.get_size_in_points()- (self.cols)/2
00764             fpy = FP(size=rcParams['ytick.labelsize'])
00765             yts = fpy.get_size_in_points() - (self.rows)/2
00766             fpa = FP(size=rcParams['axes.labelsize'])
00767             fpat = FP(size=rcParams['axes.titlesize'])
00768             axsize =  fpa.get_size_in_points()
00769             tsize =  fpat.get_size_in_points()-(self.cols)/2
00770             for sp in self.subplots:
00771                 ax = sp['axes']
00772                 ax.title.set_size(tsize)
00773                 setp(ax.get_xticklabels(), fontsize=xts)
00774                 setp(ax.get_yticklabels(), fontsize=yts)
00775                 off = 0
00776                 if self.cols > 1: off = self.cols
00777                 ax.xaxis.label.set_size(axsize-off)
00778                 off = 0
00779                 if self.rows > 1: off = self.rows
00780                 ax.yaxis.label.set_size(axsize-off)
00781 
00782     def subplot(self, i=None, inc=None):
00783         """
00784         Set the subplot to the 0-relative panel number as defined by one or
00785         more invokations of set_panels().
00786         """
00787         l = len(self.subplots)
00788         if l:
00789             if i is not None:
00790                 self.i = i
00791 
00792             if inc is not None:
00793                 self.i += inc
00794 
00795             self.i %= l
00796             self.axes  = self.subplots[self.i]['axes']
00797             self.lines = self.subplots[self.i]['lines']
00798 
00799     def text(self, *args, **kwargs):
00800         """
00801         Add text to the figure.
00802         """
00803         self.figure.text(*args, **kwargs)
00804         self.show()
00805 
00806     def vline_with_label(self, x, y, label,
00807                          location='bottom', rotate=0.0, **kwargs):
00808         """
00809         Plot a vertical line with label.
00810         It takes "world" values fo x and y.
00811         """
00812         ax = self.axes
00813         # need this to suppress autoscaling during this function
00814         self.axes.set_autoscale_on(False)
00815         ymin = 0.0
00816         ymax = 1.0
00817         valign = 'center'
00818         if location.lower() == 'top':
00819             y = max(0.0, y)
00820         elif location.lower() == 'bottom':
00821             y = min(0.0, y)
00822         lbloffset = 0.06
00823         # a rough estimate for the bb of the text
00824         if rotate > 0.0: lbloffset = 0.03*len(label)
00825         peakoffset = 0.01
00826         xy = None
00827         xy0 = None
00828         # matplotlib api change 0.98 is using transform now
00829         if hasattr(ax.transData, "inverse_xy_tup"):
00830             # get relative coords
00831             xy0 = ax.transData.xy_tup((x,y))
00832             xy = ax.transAxes.inverse_xy_tup(xy0)
00833         else:
00834             xy0 = ax.transData.transform((x,y))
00835             # get relative coords
00836             xy = ax.transAxes.inverted().transform(xy0)
00837         if location.lower() == 'top':
00838             ymax = 1.0-lbloffset
00839             ymin = xy[1]+peakoffset
00840             valign = 'bottom'
00841             ylbl = ymax+0.01
00842         elif location.lower() == 'bottom':
00843             ymin = lbloffset
00844             ymax = xy[1]-peakoffset
00845             valign = 'top'
00846             ylbl = ymin-0.01
00847         trans = blended_transform_factory(ax.transData, ax.transAxes)
00848         l = ax.axvline(x, ymin, ymax, color='black', **kwargs)
00849         t = ax.text(x, ylbl ,label, verticalalignment=valign,
00850                                     horizontalalignment='center',
00851                     rotation=rotate,transform = trans)
00852         self.axes.set_autoscale_on(True)
00853 
00854     def _alive(self):
00855         # Return True if the GUI alives.
00856         if (not self.is_dead) and \
00857                self.figmgr and hasattr(self.figmgr, "num"):
00858             figid = self.figmgr.num
00859             # Make sure figid=0 is what asapplotter expects.
00860             # It might be already destroied/overridden by matplotlib
00861             # commands or other methods using asaplot.
00862             return _pylab_helpers.Gcf.has_fignum(figid) and \
00863                    (self.figmgr == _pylab_helpers.Gcf.get_fig_manager(figid))
00864         return False