source: trunk/python/asaplotbase.py @ 2693

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

New Development: Yes

JIRA Issue: Yes (Trac-287)

Ready for Test: Yes

Interface Changes: Yes

What Interface Changed: a new method, asapplotter.plotpointings2

Test Programs:

Put in Release Notes: No

Module(s): asapplotter, sdplot

Description:

a new method, asapplotter.plotpointings2, is created.
This method will be supposed to replace asapplotter.plotpointing
in near future if there's no issue found.
plotpointings2 plots pointing directions of a scantable.
It is possible to plot pointings of different source type, scanno,
ifno, polno, or beamno in different colors by setting the 'colorby'
paramter. When showline=True, the scan pattern is plotted in dotted
line.
This function alway plots pointings on ASAP plotter and works properly
with custom toolbar.


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