source: branches/alma/python/asaplotbase.py @ 1723

Last change on this file since 1723 was 1723, checked in by Kana Sugimoto, 14 years ago

New Development: No

JIRA Issue: Yes (CAS-1801, CAS-2064)

Ready to Release: Yes

Interface Changes: Yes

What Interface Changed:
Three methods, print_headder(), set_panellayout() and _reset_panellayout()
are added to the class asapplotter.
A parameter layout (list) is added to set_layout() in asaplotbase class.

Test Programs: run sdplot with header & plotstyle=True + layout parameter set.

Put in Release Notes: Yes

Module(s): sdplot() task.

Description:

  1. asapplotter.print_header(plot=True, fontsize=9, logger=False, selstr=, extrastr=): prints scantable header on the plot and/or logger (see help doc for parameter details). Note that the header information will not overlayed to the plot by plotazel() and plotpointing().
  2. set_panellayout(layout=[],refresh=True): sets the layout of subplots. layout is a list of subplots layout in figure coordinate (0-1) in order of [left, bottom, right, top, horizontal space btw panels, vertical space btw panels]
  3. _reset_panellayout(): resets the layout of subplots to matplotlib rc value.
  4. a member variable 'asapplotter._panellayout' (list) is specified to store layout values.


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