source: trunk/python/asaplotbase.py @ 2697

Last change on this file since 2697 was 2697, checked in by Kana Sugimoto, 11 years ago

New Development: No

JIRA Issue: No

Ready for Test: Yes

Interface Changes: No

What Interface Changed:

Test Programs: iterate pages

Put in Release Notes: No

Module(s): asapplotter and sdplot

Description: An attempt to speed-up page iterations in ASAP plotter.


  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 29.9 KB
Line 
1"""
2ASAP plotting class based on matplotlib.
3"""
4
5import sys
6from re import match
7import matplotlib
8
9from matplotlib.figure import Figure, Text
10from matplotlib.font_manager import FontProperties as FP
11from numpy import sqrt
12from matplotlib import rc, rcParams
13from matplotlib.ticker import OldScalarFormatter
14from matplotlib import _pylab_helpers
15
16from asap.parameters import rcParams as asaprcParams
17from asap.logging import asaplog
18
19# API change in mpl >= 0.98
20try:
21    from matplotlib.transforms import blended_transform_factory
22except ImportError:
23    from matplotlib.transforms import blend_xy_sep_transform as blended_transform_factory
24
25mvers = matplotlib.__version__.split(".")
26if int(mvers[0]) == 0 and int(mvers[1]) < 99:
27    #print "Warning: matplotlib version < 0.87. This might cause errors. Please upgrade."
28    asaplog.push( "matplotlib version < 0.99. This might cause errors. Please upgrade." )
29    asaplog.post( 'WARN' )
30
31class asaplotbase:
32    """
33    ASAP plotting base class based on matplotlib.
34    """
35
36    def __init__(self, rows=1, cols=0, title='', size=None, buffering=False):
37        """
38        Create a new instance of the ASAPlot plotting class.
39
40        If rows < 1 then a separate call to set_panels() is required to define
41        the panel layout; refer to the doctext for set_panels().
42        """
43        self.is_dead = False
44        self.figure = Figure(figsize=size, facecolor='#ddddee')
45        self.canvas = None
46
47        self.set_title(title)
48        self.subplots = []
49        if rows > 0:
50            self.set_panels(rows, cols)
51
52        # Set matplotlib default colour sequence.
53        self.colormap = "green red black cyan magenta orange blue purple yellow pink".split()
54
55        c = asaprcParams['plotter.colours']
56        if isinstance(c,str) and len(c) > 0:
57            self.colormap = c.split()
58
59        self.lsalias = {"line":  '-', #[1,0],
60                        "dashdot": '-.',  #[4,2,1,2],
61                        "dashed" : '--',  #[4,2,4,2],
62                        "dotted" : ':',  #[1,2],
63                        "dashdotdot": [4,2,1,2,1,2],
64                        "dashdashdot": [4,2,4,2,1,2]
65                        }
66
67        styles = "line dashed dotted dashdot".split()
68        c = asaprcParams['plotter.linestyles']
69        if isinstance(c,str) and len(c) > 0:
70            styles = c.split()
71        s = []
72        for ls in styles:
73            if self.lsalias.has_key(ls):
74                s.append(self.lsalias.get(ls))
75            else:
76                s.append('-')
77        self.linestyles = s
78
79        self.color = 0;
80        self.linestyle = 0;
81        self.attributes = {}
82        self.loc = 0
83
84        self.buffering = buffering
85
86        self.events = {'button_press':None,
87                       'button_release':None,
88                       'motion_notify':None}
89
90    def clear(self):
91        """
92        Delete all lines from the current subplot.
93        Line numbering will restart from 0.
94        """
95
96        #for i in range(len(self.lines)):
97        #   self.delete(i)
98        self.axes.clear()
99        self.color = 0
100        self.lines = []
101        self.subplots[self.i]['lines'] = self.lines
102
103    def palette(self, color, colormap=None, linestyle=0, linestyles=None):
104        if colormap:
105            if isinstance(colormap,list):
106                self.colormap = colormap
107            elif isinstance(colormap,str):
108                self.colormap = colormap.split()
109        if 0 <= color < len(self.colormap):
110            self.color = color
111        if linestyles:
112            self.linestyles = []
113            if isinstance(linestyles,list):
114                styles = linestyles
115            elif isinstance(linestyles,str):
116                styles = linestyles.split()
117            for ls in styles:
118                if self.lsalias.has_key(ls):
119                    self.linestyles.append(self.lsalias.get(ls))
120                else:
121                    self.linestyles.append(self.lsalias.get('line'))
122        if 0 <= linestyle < len(self.linestyles):
123            self.linestyle = linestyle
124
125    def delete(self, numbers=None):
126        """
127        Delete the 0-relative line number, default is to delete the last.
128        The remaining lines are NOT renumbered.
129        """
130
131        if numbers is None: numbers = [len(self.lines)-1]
132
133        if not hasattr(numbers, '__iter__'):
134            numbers = [numbers]
135
136        for number in numbers:
137            if 0 <= number < len(self.lines):
138                if self.lines[number] is not None:
139                    for line in self.lines[number]:
140                        line.set_linestyle('None')
141                        self.lines[number] = None
142        self.show()
143
144    def get_line(self):
145        """
146        Get the current default line attributes.
147        """
148        return self.attributes
149
150
151    def hist(self, x=None, y=None, fmt=None, add=None):
152        """
153        Plot a histogram.  N.B. the x values refer to the start of the
154        histogram bin.
155
156        fmt is the line style as in plot().
157        """
158        from numpy import array
159        from numpy.ma import MaskedArray
160        if x is None:
161            if y is None: return
162            x = range(len(y))
163
164        if len(x) != len(y):
165            return
166        l2 = 2*len(x)
167        x2 = range(l2)
168        y2 = range(12)
169        y2 = range(l2)
170        m2 = range(l2)
171        ymsk = None
172        ydat = None
173        if hasattr(y, "raw_mask"):
174            # numpy < 1.1
175            ymsk = y.raw_mask()
176            ydat = y.raw_data()
177        else:
178            ymsk = y.mask
179            ydat = y.data
180        for i in range(l2):
181            x2[i] = x[i/2]
182            m2[i] = ymsk[i/2]
183
184        y2[0] = 0.0
185        for i in range(1,l2):
186            y2[i] = ydat[(i-1)/2]
187
188        self.plot(x2, MaskedArray(y2,mask=m2,copy=0), fmt, add)
189
190
191    def hold(self, hold=True):
192        """
193        Buffer graphics until subsequently released.
194        """
195        self.buffering = hold
196
197
198    def legend(self, loc=None):
199        """
200        Add a legend to the plot.
201
202        Any other value for loc else disables the legend:
203             1: upper right
204             2: upper left
205             3: lower left
206             4: lower right
207             5: right
208             6: center left
209             7: center right
210             8: lower center
211             9: upper center
212            10: center
213
214        """
215        if isinstance(loc, int):
216            self.loc = None
217            if 0 <= loc <= 10: self.loc = loc
218        else:
219            self.loc = None
220        #self.show()
221
222
223    def plot(self, x=None, y=None, fmt=None, add=None):
224        """
225        Plot the next line in the current frame using the current line
226        attributes.  The ASAPlot graphics window will be mapped and raised.
227
228        The argument list works a bit like the matlab plot() function.
229        """
230        if x is None:
231            if y is None: return
232            x = range(len(y))
233
234        elif y is None:
235            y = x
236            x = range(len(y))
237        if fmt is None:
238            line = self.axes.plot(x, y)
239        else:
240            line = self.axes.plot(x, y, fmt)
241        # add a picker to lines for spectral value mode.
242        # matplotlib.axes.plot returns a list of line object (1 element)
243        line[0].set_picker(5.0)
244
245        # Add to an existing line?
246        i = None
247        if add is None or len(self.lines) < add < 0:
248            # Don't add.
249            self.lines.append(line)
250            i = len(self.lines) - 1
251        else:
252            if add == 0: add = len(self.lines)
253            i = add - 1
254            self.lines[i].extend(line)
255
256        # Set/reset attributes for the line.
257        gotcolour = False
258        for k, v in self.attributes.iteritems():
259            if k == 'color': gotcolour = True
260            for segment in self.lines[i]:
261                getattr(segment, "set_%s"%k)(v)
262
263        if not gotcolour and len(self.colormap):
264            for segment in self.lines[i]:
265                getattr(segment, "set_color")(self.colormap[self.color])
266                if len(self.colormap)  == 1:
267                    getattr(segment, "set_dashes")(self.linestyles[self.linestyle])
268
269            self.color += 1
270            if self.color >= len(self.colormap):
271                self.color = 0
272
273            if len(self.colormap) == 1:
274                self.linestyle += 1
275            if self.linestyle >= len(self.linestyles):
276                self.linestyle = 0
277
278        self.show()
279
280
281    def position(self):
282        """
283        Use the mouse to get a position from a graph.
284        """
285
286        def position_disable(event):
287            self.register('button_press', None)
288            print '%.4f, %.4f' % (event.xdata, event.ydata)
289
290        print 'Press any mouse button...'
291        self.register('button_press', position_disable)
292
293
294    def get_region(self):
295        pos = []
296        print "Please select the bottom/left point"
297        pos.append(self.figure.ginput(n=1, show_clicks=False)[0])
298        print "Please select the top/right point"
299        pos.append(self.figure.ginput(n=1, show_clicks=False)[0])
300        return pos
301
302    def get_point(self):
303        print "Please select the point"
304        pt = self.figure.ginput(n=1, show_clicks=False)
305        if pt:
306            return pt[0]
307        else:
308            return None
309
310    def region(self):
311        """
312        Use the mouse to get a rectangular region from a plot.
313
314        The return value is [x0, y0, x1, y1] in world coordinates.
315        """
316
317        def region_start(event):
318            self.rect = {'x': event.x, 'y': event.y,
319                         'world': [event.xdata, event.ydata,
320                                   event.xdata, event.ydata]}
321            self.register('button_press', None)
322            self.register('motion_notify', region_draw)
323            self.register('button_release', region_disable)
324
325        def region_draw(event):
326            self.figmgr.toolbar.draw_rubberband(event, event.x, event.y,
327                                                self.rect['x'], self.rect['y'])
328
329        def region_disable(event):
330            self.register('motion_notify', None)
331            self.register('button_release', None)
332
333            self.rect['world'][2:4] = [event.xdata, event.ydata]
334            print '(%.2f, %.2f)  (%.2f, %.2f)' % (self.rect['world'][0],
335                self.rect['world'][1], self.rect['world'][2],
336                self.rect['world'][3])
337            self.figmgr.toolbar.release(event)
338
339        self.register('button_press', region_start)
340
341        # This has to be modified to block and return the result (currently
342        # printed by region_disable) when that becomes possible in matplotlib.
343
344        return [0.0, 0.0, 0.0, 0.0]
345
346
347    def register(self, type=None, func=None):
348        """
349        Register, reregister, or deregister events of type 'button_press',
350        'button_release', or 'motion_notify'.
351
352        The specified callback function should have the following signature:
353
354            def func(event)
355
356        where event is an MplEvent instance containing the following data:
357
358            name                # Event name.
359            canvas              # FigureCanvas instance generating the event.
360            x      = None       # x position - pixels from left of canvas.
361            y      = None       # y position - pixels from bottom of canvas.
362            button = None       # Button pressed: None, 1, 2, 3.
363            key    = None       # Key pressed: None, chr(range(255)), shift,
364                                  win, or control
365            inaxes = None       # Axes instance if cursor within axes.
366            xdata  = None       # x world coordinate.
367            ydata  = None       # y world coordinate.
368
369        For example:
370
371            def mouse_move(event):
372                print event.xdata, event.ydata
373
374            a = asaplot()
375            a.register('motion_notify', mouse_move)
376
377        If func is None, the event is deregistered.
378
379        Note that in TkAgg keyboard button presses don't generate an event.
380        """
381
382        if not self.events.has_key(type): return
383
384        if func is None:
385            if self.events[type] is not None:
386                # It's not clear that this does anything.
387                self.canvas.mpl_disconnect(self.events[type])
388                self.events[type] = None
389
390                # It seems to be necessary to return events to the toolbar. <-- Not ture. 2010.Jul.14.kana.
391                #if type == 'motion_notify':
392                #    self.canvas.mpl_connect(type + '_event',
393                #        self.figmgr.toolbar.mouse_move)
394                #elif type == 'button_press':
395                #    self.canvas.mpl_connect(type + '_event',
396                #        self.figmgr.toolbar.press)
397                #elif type == 'button_release':
398                #    self.canvas.mpl_connect(type + '_event',
399                #        self.figmgr.toolbar.release)
400
401        else:
402            self.events[type] = self.canvas.mpl_connect(type + '_event', func)
403
404
405    def release(self):
406        """
407        Release buffered graphics.
408        """
409        self.buffering = False
410        self.show()
411
412
413    def save(self, fname=None, orientation=None, dpi=None, papertype=None):
414        """
415        Save the plot to a file.
416
417        fname is the name of the output file.  The image format is determined
418        from the file suffix; 'png', 'ps', and 'eps' are recognized.  If no
419        file name is specified 'yyyymmdd_hhmmss.png' is created in the current
420        directory.
421        """
422        from asap import rcParams
423        if papertype is None:
424            papertype = rcParams['plotter.papertype']
425        if fname is None:
426            from datetime import datetime
427            dstr = datetime.now().strftime('%Y%m%d_%H%M%S')
428            fname = 'asap'+dstr+'.png'
429
430        d = ['png','.ps','eps', 'svg']
431
432        from os.path import expandvars
433        fname = expandvars(fname)
434
435        if fname[-3:].lower() in d:
436            try:
437                if fname[-3:].lower() == ".ps":
438                    from matplotlib import __version__ as mv
439                    w = self.figure.get_figwidth()
440                    h = self.figure.get_figheight()
441
442                    if orientation is None:
443                        # oriented
444                        if w > h:
445                            orientation = 'landscape'
446                        else:
447                            orientation = 'portrait'
448                    from matplotlib.backends.backend_ps import papersize
449                    pw,ph = papersize[papertype.lower()]
450                    ds = None
451                    if orientation == 'landscape':
452                        ds = min(ph/w, pw/h)
453                    else:
454                        ds = min(pw/w, ph/h)
455                    ow = ds * w
456                    oh = ds * h
457                    self.figure.set_size_inches((ow, oh))
458                    self.figure.savefig(fname, orientation=orientation,
459                                        papertype=papertype.lower())
460                    self.figure.set_size_inches((w, h))
461                    print 'Written file %s' % (fname)
462                else:
463                    if dpi is None:
464                        dpi =150
465                    self.figure.savefig(fname,dpi=dpi)
466                    print 'Written file %s' % (fname)
467            except IOError, msg:
468                #print 'Failed to save %s: Error msg was\n\n%s' % (fname, err)
469                asaplog.post()
470                asaplog.push('Failed to save %s: Error msg was\n\n%s' % (fname, str(msg)))
471                asaplog.post( 'ERROR' )
472                return
473        else:
474            #print "Invalid image type. Valid types are:"
475            #print "'ps', 'eps', 'png'"
476            asaplog.push( "Invalid image type. Valid types are:" )
477            asaplog.push( "'ps', 'eps', 'png', 'svg'" )
478            asaplog.post('WARN')
479
480
481    def set_axes(self, what=None, *args, **kwargs):
482        """
483        Set attributes for the axes by calling the relevant Axes.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
491        key = "colour"
492        if kwargs.has_key(key):
493            val = kwargs.pop(key)
494            kwargs["color"] = val
495
496        getattr(self.axes, "set_%s"%what)(*args, **kwargs)
497
498        self.show(hardrefresh=False)
499
500
501    def set_figure(self, what=None, *args, **kwargs):
502        """
503        Set attributes for the figure by calling the relevant Figure.set_*()
504        method.  Colour translation is done as described in the doctext
505        for palette().
506        """
507
508        if what is None: return
509        if what[-6:] == 'colour': what = what[:-6] + 'color'
510        #if what[-5:] == 'color' and len(args):
511        #    args = (get_colour(args[0]),)
512
513        newargs = {}
514        for k, v in kwargs.iteritems():
515            k = k.lower()
516            if k == 'colour': k = 'color'
517            newargs[k] = v
518
519        getattr(self.figure, "set_%s"%what)(*args, **newargs)
520        self.show(hardrefresh=False)
521
522
523    def set_limits(self, xlim=None, ylim=None):
524        """
525        Set x-, and y-limits for each subplot.
526
527        xlim = [xmin, xmax] as in axes.set_xlim().
528        ylim = [ymin, ymax] as in axes.set_ylim().
529        """
530        for s in self.subplots:
531            self.axes  = s['axes']
532            self.lines = s['lines']
533            oldxlim =  list(self.axes.get_xlim())
534            oldylim =  list(self.axes.get_ylim())
535            if xlim is not None:
536                for i in range(len(xlim)):
537                    if xlim[i] is not None:
538                        oldxlim[i] = xlim[i]
539            if ylim is not None:
540                for i in range(len(ylim)):
541                    if ylim[i] is not None:
542                        oldylim[i] = ylim[i]
543            self.axes.set_xlim(oldxlim)
544            self.axes.set_ylim(oldylim)
545        return
546
547
548    def set_line(self, number=None, **kwargs):
549        """
550        Set attributes for the specified line, or else the next line(s)
551        to be plotted.
552
553        number is the 0-relative number of a line that has already been
554        plotted.  If no such line exists, attributes are recorded and used
555        for the next line(s) to be plotted.
556
557        Keyword arguments specify Line2D attributes, e.g. color='r'.  Do
558
559            import matplotlib
560            help(matplotlib.lines)
561
562        The set_* methods of class Line2D define the attribute names and
563        values.  For non-US usage, 'colour' is recognized as synonymous with
564        'color'.
565
566        Set the value to None to delete an attribute.
567
568        Colour translation is done as described in the doctext for palette().
569        """
570
571        redraw = False
572        for k, v in kwargs.iteritems():
573            k = k.lower()
574            if k == 'colour': k = 'color'
575
576            if 0 <= number < len(self.lines):
577                if self.lines[number] is not None:
578                    for line in self.lines[number]:
579                        getattr(line, "set_%s"%k)(v)
580                    redraw = True
581            else:
582                if v is None:
583                    del self.attributes[k]
584                else:
585                    self.attributes[k] = v
586
587        if redraw: self.show(hardrefresh=False)
588
589
590    #def set_panels(self, rows=1, cols=0, n=-1, nplots=-1, ganged=True):
591    def set_panels(self, rows=1, cols=0, n=-1, nplots=-1, margin=None,ganged=True):
592        """
593        Set the panel layout.
594
595        rows and cols, if cols != 0, specify the number of rows and columns in
596        a regular layout.   (Indexing of these panels in matplotlib is row-
597        major, i.e. column varies fastest.)
598
599        cols == 0 is interpreted as a retangular layout that accomodates
600        'rows' panels, e.g. rows == 6, cols == 0 is equivalent to
601        rows == 2, cols == 3.
602
603        0 <= n < rows*cols is interpreted as the 0-relative panel number in
604        the configuration specified by rows and cols to be added to the
605        current figure as its next 0-relative panel number (i).  This allows
606        non-regular panel layouts to be constructed via multiple calls.  Any
607        other value of n clears the plot and produces a rectangular array of
608        empty panels.  The number of these may be limited by nplots.
609        """
610        if n < 0 and len(self.subplots):
611            self.figure.clear()
612            self.set_title()
613
614        if margin:
615            lef, bot, rig, top, wsp, hsp = margin
616            self.figure.subplots_adjust(
617                left=lef,bottom=bot,right=rig,top=top,wspace=wsp,hspace=hsp)
618            del lef,bot,rig,top,wsp,hsp
619
620        if rows < 1: rows = 1
621
622        if cols <= 0:
623            i = int(sqrt(rows))
624            if i*i < rows: i += 1
625            cols = i
626
627            if i*(i-1) >= rows: i -= 1
628            rows = i
629
630        if 0 <= n < rows*cols:
631            i = len(self.subplots)
632
633            self.subplots.append({})
634
635            self.subplots[i]['axes']  = self.figure.add_subplot(rows,
636                                            cols, n+1)
637            self.subplots[i]['lines'] = []
638
639            if i == 0: self.subplot(0)
640
641            self.rows = 0
642            self.cols = 0
643
644        else:
645            self.subplots = []
646
647            if nplots < 1 or rows*cols < nplots:
648                nplots = rows*cols
649            if ganged:
650                hsp,wsp = None,None
651                if rows > 1: hsp = 0.0001
652                if cols > 1: wsp = 0.0001
653                self.figure.subplots_adjust(wspace=wsp,hspace=hsp)
654            for i in range(nplots):
655                self.subplots.append({})
656                self.subplots[i]['lines'] = []
657                if not ganged:
658                    self.subplots[i]['axes'] = self.figure.add_subplot(rows,
659                                                cols, i+1)
660                    if asaprcParams['plotter.axesformatting'] != 'mpl':
661                        self.subplots[i]['axes'].xaxis.set_major_formatter(OldScalarFormatter())
662                else:
663                    if i == 0:
664                        self.subplots[i]['axes'] = self.figure.add_subplot(rows,
665                                                cols, i+1)
666                        if asaprcParams['plotter.axesformatting'] != 'mpl':
667
668                            self.subplots[i]['axes'].xaxis.set_major_formatter(OldScalarFormatter())
669                    else:
670                        self.subplots[i]['axes'] = self.figure.add_subplot(rows,
671                                                cols, i+1,
672                                                sharex=self.subplots[0]['axes'],
673                                                sharey=self.subplots[0]['axes'])
674
675                    # Suppress tick labelling for interior subplots.
676                    if i <= (rows-1)*cols - 1:
677                        if i+cols < nplots:
678                            # Suppress x-labels for frames width
679                            # adjacent frames
680                            for tick in self.subplots[i]['axes'].xaxis.majorTicks:
681                                tick.label1On = False
682                            #self.subplots[i]['axes'].xaxis.label.set_visible(False)
683                    if i%cols:
684                        # Suppress y-labels for frames not in the left column.
685                        for tick in self.subplots[i]['axes'].yaxis.majorTicks:
686                            tick.label1On = False
687                        #self.subplots[i]['axes'].yaxis.label.set_visible(False)
688                    # disable the first tick of [1:ncol-1] of the last row
689                    #if i+1 < nplots:
690                    #    self.subplots[i]['axes'].xaxis.majorTicks[0].label1On = False
691                # set axes label state for interior subplots.
692                if i%cols:
693                    self.subplots[i]['axes'].yaxis.label.set_visible(False)
694                if (i <= (rows-1)*cols - 1) and (i+cols < nplots):
695                    self.subplots[i]['axes'].xaxis.label.set_visible(False)
696            self.rows = rows
697            self.cols = cols
698            self.subplot(0)
699        del rows,cols,n,nplots,margin,ganged,i
700
701
702    def tidy(self):
703        # this needs to be exceuted after the first "refresh"
704        nplots = len(self.subplots)
705        if nplots == 1: return
706        for i in xrange(nplots):
707            ax = self.subplots[i]['axes']
708            if i%self.cols:
709                ax.xaxis.majorTicks[0].label1On = False
710            else:
711                if i != 0:
712                    ax.yaxis.majorTicks[-1].label1On = False
713            ## set axes label state for interior subplots.
714            #innerax=False
715            #if i%self.cols:
716            #    ax.yaxis.label.set_visible(innerax)
717            #if (i <= (self.rows-1)*self.cols - 1) and (i+self.cols < nplots):
718            #    ax.xaxis.label.set_visible(innerax)
719           
720
721    def set_title(self, title=None):
722        """
723        Set the title of the plot window.  Use the previous title if title is
724        omitted.
725        """
726        if title is not None:
727            self.title = title
728
729        self.figure.text(0.5, 0.95, self.title, horizontalalignment='center')
730
731
732    def show(self, hardrefresh=True):
733        """
734        Show graphics dependent on the current buffering state.
735        """
736        if not hardrefresh: return
737        if not self.buffering:
738            if self.loc is not None:
739                for sp in self.subplots:
740                    lines  = []
741                    labels = []
742                    i = 0
743                    for line in sp['lines']:
744                        i += 1
745                        if line is not None:
746                            lines.append(line[0])
747                            lbl = line[0].get_label()
748                            if lbl == '':
749                                lbl = str(i)
750                            labels.append(lbl)
751
752                    if len(lines):
753                        fp = FP(size=rcParams['legend.fontsize'])
754                        #fsz = fp.get_size_in_points() - len(lines)
755                        fsz = fp.get_size_in_points() - max(len(lines),self.cols)
756                        #fp.set_size(max(fsz,6))
757                        fp.set_size(max(fsz,8))
758                        sp['axes'].legend(tuple(lines), tuple(labels),
759                                          self.loc, prop=fp)
760                    #else:
761                    #    sp['axes'].legend((' '))
762
763            from matplotlib.artist import setp
764            fpx = FP(size=rcParams['xtick.labelsize'])
765            xts = fpx.get_size_in_points()- (self.cols)/2
766            fpy = FP(size=rcParams['ytick.labelsize'])
767            yts = fpy.get_size_in_points() - (self.rows)/2
768            fpa = FP(size=rcParams['axes.labelsize'])
769            fpat = FP(size=rcParams['axes.titlesize'])
770            axsize =  fpa.get_size_in_points()
771            tsize =  fpat.get_size_in_points()-(self.cols)/2
772            for sp in self.subplots:
773                ax = sp['axes']
774                ax.title.set_size(tsize)
775                setp(ax.get_xticklabels(), fontsize=xts)
776                setp(ax.get_yticklabels(), fontsize=yts)
777                off = 0
778                if self.cols > 1: off = self.cols
779                ax.xaxis.label.set_size(axsize-off)
780                off = 0
781                if self.rows > 1: off = self.rows
782                ax.yaxis.label.set_size(axsize-off)
783
784    def subplot(self, i=None, inc=None):
785        """
786        Set the subplot to the 0-relative panel number as defined by one or
787        more invokations of set_panels().
788        """
789        l = len(self.subplots)
790        if l:
791            if i is not None:
792                self.i = i
793
794            if inc is not None:
795                self.i += inc
796
797            self.i %= l
798            self.axes  = self.subplots[self.i]['axes']
799            self.lines = self.subplots[self.i]['lines']
800
801    def text(self, *args, **kwargs):
802        """
803        Add text to the figure.
804        """
805        self.figure.text(*args, **kwargs)
806        self.show()
807
808    def vline_with_label(self, x, y, label,
809                         location='bottom', rotate=0.0, **kwargs):
810        """
811        Plot a vertical line with label.
812        It takes "world" values fo x and y.
813        """
814        ax = self.axes
815        # need this to suppress autoscaling during this function
816        self.axes.set_autoscale_on(False)
817        ymin = 0.0
818        ymax = 1.0
819        valign = 'center'
820        if location.lower() == 'top':
821            y = max(0.0, y)
822        elif location.lower() == 'bottom':
823            y = min(0.0, y)
824        lbloffset = 0.06
825        # a rough estimate for the bb of the text
826        if rotate > 0.0: lbloffset = 0.03*len(label)
827        peakoffset = 0.01
828        xy = None
829        xy0 = None
830        # matplotlib api change 0.98 is using transform now
831        if hasattr(ax.transData, "inverse_xy_tup"):
832            # get relative coords
833            xy0 = ax.transData.xy_tup((x,y))
834            xy = ax.transAxes.inverse_xy_tup(xy0)
835        else:
836            xy0 = ax.transData.transform((x,y))
837            # get relative coords
838            xy = ax.transAxes.inverted().transform(xy0)
839        if location.lower() == 'top':
840            ymax = 1.0-lbloffset
841            ymin = xy[1]+peakoffset
842            valign = 'bottom'
843            ylbl = ymax+0.01
844        elif location.lower() == 'bottom':
845            ymin = lbloffset
846            ymax = xy[1]-peakoffset
847            valign = 'top'
848            ylbl = ymin-0.01
849        trans = blended_transform_factory(ax.transData, ax.transAxes)
850        l = ax.axvline(x, ymin, ymax, color='black', **kwargs)
851        t = ax.text(x, ylbl ,label, verticalalignment=valign,
852                                    horizontalalignment='center',
853                    rotation=rotate,transform = trans)
854        self.axes.set_autoscale_on(True)
855
856    def _alive(self):
857        # Return True if the GUI alives.
858        if (not self.is_dead) and \
859               self.figmgr and hasattr(self.figmgr, "num"):
860            figid = self.figmgr.num
861            # Make sure figid=0 is what asapplotter expects.
862            # It might be already destroied/overridden by matplotlib
863            # commands or other methods using asaplot.
864            return _pylab_helpers.Gcf.has_fignum(figid) and \
865                   (self.figmgr == _pylab_helpers.Gcf.get_fig_manager(figid))
866        return False
Note: See TracBrowser for help on using the repository browser.