source: tags/Release2.1.0b/python/asapplotter.py @ 1256

Last change on this file since 1256 was 1256, checked in by mar637, 18 years ago

turned return without warning into exceptions. changed default rotation to 90 degrees. Added habdling of all 'Hz' based units.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 28.9 KB
Line 
1from asap import rcParams, print_log, selector
2from asap import NUM
3import matplotlib.axes
4import sre
5
6class asapplotter:
7    """
8    The ASAP plotter.
9    By default the plotter is set up to plot polarisations
10    'colour stacked' and scantables across panels.
11    Note:
12        Currenly it only plots 'spectra' not Tsys or
13        other variables.
14    """
15    def __init__(self, visible=None):
16        self._visible = rcParams['plotter.gui']
17        if visible is not None:
18            self._visible = visible
19        self._plotter = self._newplotter()
20
21        self._panelling = None
22        self._stacking = None
23        self.set_panelling()
24        self.set_stacking()
25        self._rows = None
26        self._cols = None
27        self._autoplot = False
28        self._minmaxx = None
29        self._minmaxy = None
30        self._datamask = None
31        self._data = None
32        self._lmap = None
33        self._title = None
34        self._ordinate = None
35        self._abcissa = None
36        self._abcunit = None
37        self._usermask = []
38        self._maskselection = None
39        self._selection = selector()
40        self._hist = rcParams['plotter.histogram']
41
42    def _translate(self, instr):
43        keys = "s b i p t".split()
44        if isinstance(instr, str):
45            for key in keys:
46                if instr.lower().startswith(key):
47                    return key
48        return None
49
50    def _newplotter(self):
51        if self._visible:
52            from asap.asaplotgui import asaplotgui as asaplot
53        else:
54            from asap.asaplot import asaplot
55        return asaplot()
56
57
58    def plot(self, scan=None):
59        """
60        Plot a scantable.
61        Parameters:
62            scan:   a scantable
63        Note:
64            If a scantable was specified in a previous call
65            to plot, no argument has to be given to 'replot'
66            NO checking is done that the abcissas of the scantable
67            are consistent e.g. all 'channel' or all 'velocity' etc.
68        """
69        if self._plotter.is_dead:
70            self._plotter = self._newplotter()
71        self._plotter.hold()
72        self._plotter.clear()
73        from asap import scantable
74        if not self._data and not scan:
75            msg = "Input is not a scantable"
76            if rcParams['verbose']:
77                print msg
78                return
79            raise TypeError(msg)
80        if isinstance(scan, scantable):
81            if self._data is not None:
82                if scan != self._data:
83                    self._data = scan
84                    # reset
85                    self._reset()
86            else:
87                self._data = scan
88                self._reset()
89        # ranges become invalid when unit changes
90        if self._abcunit and self._abcunit != self._data.get_unit():
91            self._minmaxx = None
92            self._minmaxy = None
93            self._abcunit = self._data.get_unit()
94            self._datamask = None
95        self._plot(self._data)
96        if self._minmaxy is not None:
97            self._plotter.set_limits(ylim=self._minmaxy)
98        self._plotter.release()
99        self._plotter.tidy()
100        self._plotter.show(hardrefresh=False)
101        print_log()
102        return
103
104
105    # forwards to matplotlib axes
106    def text(self, *args, **kwargs):
107        self._axes_callback("text", *args, **kwargs)
108    text. __doc__ = matplotlib.axes.Axes.text.__doc__
109    def arrow(self, *args, **kwargs):
110        self._axes_callback("arrow", *args, **kwargs)
111    arrow. __doc__ = matplotlib.axes.Axes.arrow.__doc__
112    def axvline(self, *args, **kwargs):
113        self._axes_callback("axvline", *args, **kwargs)
114    axvline. __doc__ = matplotlib.axes.Axes.axvline.__doc__
115    def axhline(self, *args, **kwargs):
116        self._axes_callback("axhline", *args, **kwargs)
117    axhline. __doc__ = matplotlib.axes.Axes.axhline.__doc__
118    def axvspan(self, *args, **kwargs):
119        self._axes_callback("axvspan", *args, **kwargs)
120        # hack to preventy mpl from redrawing the patch
121        # it seem to convert the patch into lines on every draw.
122        # This doesn't happen in a test script???
123        del self._plotter.axes.patches[-1]
124    axvspan. __doc__ = matplotlib.axes.Axes.axvspan.__doc__
125
126    def axhspan(self, *args, **kwargs):
127        self._axes_callback("axhspan", *args, **kwargs)
128        # hack to preventy mpl from redrawing the patch
129        # it seem to convert the patch into lines on every draw.
130        # This doesn't happen in a test script???
131        del self._plotter.axes.patches[-1]
132    axhspan. __doc__ = matplotlib.axes.Axes.axhspan.__doc__
133
134    def _axes_callback(self, axesfunc, *args, **kwargs):
135        panel = 0
136        if kwargs.has_key("panel"):
137            panel = kwargs.pop("panel")
138        coords = None
139        if kwargs.has_key("coords"):
140            coords = kwargs.pop("coords")
141            if coords.lower() == 'world':
142                kwargs["transform"] = self._plotter.axes.transData
143            elif coords.lower() == 'relative':
144                kwargs["transform"] = self._plotter.axes.transAxes
145        self._plotter.subplot(panel)
146        self._plotter.axes.set_autoscale_on(False)
147        getattr(self._plotter.axes, axesfunc)(*args, **kwargs)
148        self._plotter.show(False)
149        self._plotter.axes.set_autoscale_on(True)
150    # end matplotlib.axes fowarding functions
151
152    def set_mode(self, stacking=None, panelling=None):
153        """
154        Set the plots look and feel, i.e. what you want to see on the plot.
155        Parameters:
156            stacking:     tell the plotter which variable to plot
157                          as line colour overlays (default 'pol')
158            panelling:    tell the plotter which variable to plot
159                          across multiple panels (default 'scan'
160        Note:
161            Valid modes are:
162                 'beam' 'Beam' 'b':     Beams
163                 'if' 'IF' 'i':         IFs
164                 'pol' 'Pol' 'p':       Polarisations
165                 'scan' 'Scan' 's':     Scans
166                 'time' 'Time' 't':     Times
167        """
168        msg = "Invalid mode"
169        if not self.set_panelling(panelling) or \
170               not self.set_stacking(stacking):
171            if rcParams['verbose']:
172                print msg
173                return
174            else:
175                raise TypeError(msg)
176        if self._data: self.plot(self._data)
177        return
178
179    def set_panelling(self, what=None):
180        mode = what
181        if mode is None:
182             mode = rcParams['plotter.panelling']
183        md = self._translate(mode)
184        if md:
185            self._panelling = md
186            self._title = None
187            return True
188        return False
189
190    def set_layout(self,rows=None,cols=None):
191        """
192        Set the multi-panel layout, i.e. how many rows and columns plots
193        are visible.
194        Parameters:
195             rows:   The number of rows of plots
196             cols:   The number of columns of plots
197        Note:
198             If no argument is given, the potter reverts to its auto-plot
199             behaviour.
200        """
201        self._rows = rows
202        self._cols = cols
203        if self._data: self.plot(self._data)
204        return
205
206    def set_stacking(self, what=None):
207        mode = what
208        if mode is None:
209             mode = rcParams['plotter.stacking']
210        md = self._translate(mode)
211        if md:
212            self._stacking = md
213            self._lmap = None
214            return True
215        return False
216
217    def set_range(self,xstart=None,xend=None,ystart=None,yend=None):
218        """
219        Set the range of interest on the abcissa of the plot
220        Parameters:
221            [x,y]start,[x,y]end:  The start and end points of the 'zoom' window
222        Note:
223            These become non-sensical when the unit changes.
224            use plotter.set_range() without parameters to reset
225
226        """
227        if xstart is None and xend is None:
228            self._minmaxx = None
229        else:
230            self._minmaxx = [xstart,xend]
231        if ystart is None and yend is None:
232            self._minmaxy = None
233        else:
234            self._minmaxy = [ystart,yend]
235        if self._data: self.plot(self._data)
236        return
237
238    def set_legend(self, mp=None, fontsize = None, mode = 0):
239        """
240        Specify a mapping for the legend instead of using the default
241        indices:
242        Parameters:
243            mp:        a list of 'strings'. This should have the same length
244                       as the number of elements on the legend and then maps
245                       to the indeces in order. It is possible to uses latex
246                       math expression. These have to be enclosed in r'',
247                       e.g. r'$x^{2}$'
248            fontsize:  The font size of the label (default None)
249            mode:      where to display the legend
250                       Any other value for loc else disables the legend:
251                        0: auto
252                        1: upper right
253                        2: upper left
254                        3: lower left
255                        4: lower right
256                        5: right
257                        6: center left
258                        7: center right
259                        8: lower center
260                        9: upper center
261                        10: center
262
263        Example:
264             If the data has two IFs/rest frequencies with index 0 and 1
265             for CO and SiO:
266             plotter.set_stacking('i')
267             plotter.set_legend(['CO','SiO'])
268             plotter.plot()
269             plotter.set_legend([r'$^{12}CO$', r'SiO'])
270        """
271        self._lmap = mp
272        self._plotter.legend(mode)
273        if isinstance(fontsize, int):
274            from matplotlib import rc as rcp
275            rcp('legend', fontsize=fontsize)
276        if self._data:
277            self.plot(self._data)
278        return
279
280    def set_title(self, title=None, fontsize=None):
281        """
282        Set the title of the plot. If multiple panels are plotted,
283        multiple titles have to be specified.
284        Example:
285             # two panels are visible on the plotter
286             plotter.set_title(["First Panel","Second Panel"])
287        """
288        self._title = title
289        if isinstance(fontsize, int):
290            from matplotlib import rc as rcp
291            rcp('axes', titlesize=fontsize)
292        if self._data: self.plot(self._data)
293        return
294
295    def set_ordinate(self, ordinate=None, fontsize=None):
296        """
297        Set the y-axis label of the plot. If multiple panels are plotted,
298        multiple labels have to be specified.
299        Parameters:
300            ordinate:    a list of ordinate labels. None (default) let
301                         data determine the labels
302        Example:
303             # two panels are visible on the plotter
304             plotter.set_ordinate(["First Y-Axis","Second Y-Axis"])
305        """
306        self._ordinate = ordinate
307        if isinstance(fontsize, int):
308            from matplotlib import rc as rcp
309            rcp('axes', labelsize=fontsize)
310            rcp('ytick', labelsize=fontsize)
311        if self._data: self.plot(self._data)
312        return
313
314    def set_abcissa(self, abcissa=None, fontsize=None):
315        """
316        Set the x-axis label of the plot. If multiple panels are plotted,
317        multiple labels have to be specified.
318        Parameters:
319            abcissa:     a list of abcissa labels. None (default) let
320                         data determine the labels
321        Example:
322             # two panels are visible on the plotter
323             plotter.set_ordinate(["First X-Axis","Second X-Axis"])
324        """
325        self._abcissa = abcissa
326        if isinstance(fontsize, int):
327            from matplotlib import rc as rcp
328            rcp('axes', labelsize=fontsize)
329            rcp('xtick', labelsize=fontsize)
330        if self._data: self.plot(self._data)
331        return
332
333    def set_colors(self, colmap):
334        """
335        Set the colours to be used. The plotter will cycle through
336        these colours when lines are overlaid (stacking mode).
337        Parameters:
338            colmap:     a list of colour names
339        Example:
340             plotter.set_colors("red green blue")
341             # If for example four lines are overlaid e.g I Q U V
342             # 'I' will be 'red', 'Q' will be 'green', U will be 'blue'
343             # and 'V' will be 'red' again.
344        """
345        if isinstance(colmap,str):
346            colmap = colmap.split()
347        self._plotter.palette(0, colormap=colmap)
348        if self._data: self.plot(self._data)
349
350    # alias for english speakers
351    set_colours = set_colors
352
353    def set_histogram(self, hist=True, linewidth=None):
354        """
355        Enable/Disable histogram-like plotting.
356        Parameters:
357            hist:        True (default) or False. The fisrt default
358                         is taken from the .asaprc setting
359                         plotter.histogram
360        """
361        self._hist = hist
362        if isinstance(linewidth, float) or isinstance(linewidth, int):
363            from matplotlib import rc as rcp
364            rcp('lines', linewidth=linewidth)
365        if self._data: self.plot(self._data)
366
367    def set_linestyles(self, linestyles=None, linewidth=None):
368        """
369        Set the linestyles to be used. The plotter will cycle through
370        these linestyles when lines are overlaid (stacking mode) AND
371        only one color has been set.
372        Parameters:
373             linestyles:     a list of linestyles to use.
374                             'line', 'dashed', 'dotted', 'dashdot',
375                             'dashdotdot' and 'dashdashdot' are
376                             possible
377
378        Example:
379             plotter.set_colors("black")
380             plotter.set_linestyles("line dashed dotted dashdot")
381             # If for example four lines are overlaid e.g I Q U V
382             # 'I' will be 'solid', 'Q' will be 'dashed',
383             # U will be 'dotted' and 'V' will be 'dashdot'.
384        """
385        if isinstance(linestyles,str):
386            linestyles = linestyles.split()
387        self._plotter.palette(color=0,linestyle=0,linestyles=linestyles)
388        if isinstance(linewidth, float) or isinstance(linewidth, int):
389            from matplotlib import rc as rcp
390            rcp('lines', linewidth=linewidth)
391        if self._data: self.plot(self._data)
392
393    def set_font(self, family=None, style=None, weight=None, size=None):
394        """
395        Set font properties.
396        Parameters:
397            family:    one of 'sans-serif', 'serif', 'cursive', 'fantasy', 'monospace'
398            style:     one of 'normal' (or 'roman'), 'italic'  or 'oblique'
399            weight:    one of 'normal or 'bold'
400            size:      the 'general' font size, individual elements can be adjusted
401                       seperately
402        """
403        from matplotlib import rc as rcp
404        if isinstance(family, str):
405            rcp('font', family=family)
406        if isinstance(style, str):
407            rcp('font', style=style)
408        if isinstance(weight, str):
409            rcp('font', weight=weight)
410        if isinstance(size, float) or isinstance(size, int):
411            rcp('font', size=size)
412        if self._data: self.plot(self._data)
413
414    def plot_lines(self, linecat=None, doppler=0.0, deltachan=10, rotate=90.0,
415                   location=None):
416        """
417        Plot a line catalog.
418        Parameters:
419            linecat:      the linecatalog to plot
420            doppler:      the velocity shift to apply to the frequencies
421            deltachan:    the number of channels to include each side of the
422                          line to determine a local maximum/minimum
423            rotate:       the rotation (in degrees) )for the text label (default 90.0)
424            location:     the location of the line annotation from the 'top',
425                          'bottom' or alternate (None - the default)
426        Notes:
427        If the spectrum is flagged no line will be drawn in that location.
428        """
429        if not self._data:
430            raise RuntimeError("No scantable has been plotted yet.")
431        from asap._asap import linecatalog
432        if not isinstance(linecat, linecatalog):
433            raise ValueError("'linecat' isn't of type linecatalog.")
434        if not self._data.get_unit().endswith("Hz"):
435            raise RuntimeError("Can only overlay linecatalogs when data is in frequency.")
436        from matplotlib.numerix import ma
437        for j in range(len(self._plotter.subplots)):
438            self._plotter.subplot(j)
439            lims = self._plotter.axes.get_xlim()
440            for row in range(linecat.nrow()):
441                # get_frequency returns MHz
442                base = { "GHz": 1000.0, "MHz": 1.0, "Hz": 1.0e-6 }
443                restf = linecat.get_frequency(row)/base[self._data.get_unit()]
444                c = 299792.458
445                freq = restf*(1.0-doppler/c)
446                if lims[0] < freq < lims[1]:
447                    if location is None:
448                        loc = 'bottom'
449                        if row%2: loc='top'
450                    else: loc = location
451                    maxys = []
452                    for line in self._plotter.axes.lines:
453                        v = line._x
454                        asc = v[0] < v[-1]
455
456                        idx = None
457                        if not asc:
458                            if v[len(v)-1] <= freq <= v[0]:
459                                i = len(v)-1
460                                while i>=0 and v[i] < freq:
461                                    idx = i
462                                    i-=1
463                        else:
464                           if v[0] <= freq <= v[len(v)-1]:
465                                i = 0
466                                while  i<len(v) and v[i] < freq:
467                                    idx = i
468                                    i+=1
469                        if idx is not None:
470                            lower = idx - deltachan
471                            upper = idx + deltachan
472                            if lower < 0: lower = 0
473                            if upper > len(v): upper = len(v)
474                            s = slice(lower, upper)
475                            y = line._y[s]
476                            maxy = ma.maximum(y)
477                            if isinstance( maxy, float):
478                                maxys.append(maxy)
479                    if len(maxys):
480                        peak = max(maxys)
481                        if peak > self._plotter.axes.get_ylim()[1]:
482                            loc = 'bottom'
483                    else:
484                        continue
485                    self._plotter.vline_with_label(freq, peak,
486                                                   linecat.get_name(row),
487                                                   location=loc, rotate=rotate)
488        self._plotter.show(hardrefresh=False)
489
490
491    def save(self, filename=None, orientation=None, dpi=None):
492        """
493        Save the plot to a file. The know formats are 'png', 'ps', 'eps'.
494        Parameters:
495             filename:    The name of the output file. This is optional
496                          and autodetects the image format from the file
497                          suffix. If non filename is specified a file
498                          called 'yyyymmdd_hhmmss.png' is created in the
499                          current directory.
500             orientation: optional parameter for postscript only (not eps).
501                          'landscape', 'portrait' or None (default) are valid.
502                          If None is choosen for 'ps' output, the plot is
503                          automatically oriented to fill the page.
504             dpi:         The dpi of the output non-ps plot
505        """
506        self._plotter.save(filename,orientation,dpi)
507        return
508
509
510    def set_mask(self, mask=None, selection=None):
511        """
512        Set a plotting mask for a specific polarization.
513        This is useful for masking out "noise" Pangle outside a source.
514        Parameters:
515             mask:           a mask from scantable.create_mask
516             selection:      the spectra to apply the mask to.
517        Example:
518             select = selector()
519             select.setpolstrings("Pangle")
520             plotter.set_mask(mymask, select)
521        """
522        if not self._data:
523            msg = "Can only set mask after a first call to plot()"
524            if rcParams['verbose']:
525                print msg
526                return
527            else:
528                raise RuntimeError(msg)
529        if len(mask):
530            if isinstance(mask, list) or isinstance(mask, tuple):
531                self._usermask = array(mask)
532            else:
533                self._usermask = mask
534        if mask is None and selection is None:
535            self._usermask = []
536            self._maskselection = None
537        if isinstance(selection, selector):
538            self._maskselection = {'b': selection.get_beams(),
539                                   's': selection.get_scans(),
540                                   'i': selection.get_ifs(),
541                                   'p': selection.get_pols(),
542                                   't': [] }
543        else:
544            self._maskselection = None
545        self.plot(self._data)
546
547    def _slice_indeces(self, data):
548        mn = self._minmaxx[0]
549        mx = self._minmaxx[1]
550        asc = data[0] < data[-1]
551        start=0
552        end = len(data)-1
553        inc = 1
554        if not asc:
555            start = len(data)-1
556            end = 0
557            inc = -1
558        # find min index
559        while start > 0 and data[start] < mn:
560            start+= inc
561        # find max index
562        while end > 0 and data[end] > mx:
563            end-=inc
564        if end > 0: end +=1
565        if start > end:
566            return end,start
567        return start,end
568
569    def _reset(self):
570        self._usermask = []
571        self._usermaskspectra = None
572        self.set_selection(None, False)
573
574    def _plot(self, scan):
575        savesel = scan.get_selection()
576        sel = savesel +  self._selection
577        d0 = {'s': 'SCANNO', 'b': 'BEAMNO', 'i':'IFNO',
578              'p': 'POLNO', 'c': 'CYCLENO', 't' : 'TIME' }
579        order = [d0[self._panelling],d0[self._stacking]]
580        sel.set_order(order)
581        scan.set_selection(sel)
582        d = {'b': scan.getbeam, 's': scan.getscan,
583             'i': scan.getif, 'p': scan.getpol, 't': scan._gettime }
584
585        polmodes = dict(zip(self._selection.get_pols(),
586                            self._selection.get_poltypes()))
587        # this returns either a tuple of numbers or a length  (ncycles)
588        # convert this into lengths
589        n0,nstack0 = self._get_selected_n(scan)
590        if isinstance(n0, int): n = n0
591        else: n = len(n0)
592        if isinstance(nstack0, int): nstack = nstack0
593        else: nstack = len(nstack0)
594        maxpanel, maxstack = 16,8
595        if n > maxpanel or nstack > maxstack:
596            from asap import asaplog
597            maxn = 0
598            if nstack > maxstack: maxn = maxstack
599            if n > maxpanel: maxn = maxpanel
600            msg ="Scan to be plotted contains more than %d selections.\n" \
601                  "Selecting first %d selections..." % (maxn, maxn)
602            asaplog.push(msg)
603            print_log()
604            n = min(n,maxpanel)
605            nstack = min(nstack,maxstack)
606        if n > 1:
607            ganged = rcParams['plotter.ganged']
608            if self._rows and self._cols:
609                n = min(n,self._rows*self._cols)
610                self._plotter.set_panels(rows=self._rows,cols=self._cols,
611                                         nplots=n,ganged=ganged)
612            else:
613                self._plotter.set_panels(rows=n,cols=0,nplots=n,ganged=ganged)
614        else:
615            self._plotter.set_panels()
616        r=0
617        nr = scan.nrow()
618        a0,b0 = -1,-1
619        allxlim = []
620        allylim = []
621        newpanel=True
622        panelcount,stackcount = 0,0
623        while r < nr:
624            a = d[self._panelling](r)
625            b = d[self._stacking](r)
626            if a > a0 and panelcount < n:
627                if n > 1:
628                    self._plotter.subplot(panelcount)
629                self._plotter.palette(0)
630                #title
631                xlab = self._abcissa and self._abcissa[panelcount] \
632                       or scan._getabcissalabel()
633                ylab = self._ordinate and self._ordinate[panelcount] \
634                       or scan._get_ordinate_label()
635                self._plotter.set_axes('xlabel',xlab)
636                self._plotter.set_axes('ylabel',ylab)
637                lbl = self._get_label(scan, r, self._panelling, self._title)
638                if isinstance(lbl, list) or isinstance(lbl, tuple):
639                    if 0 <= panelcount < len(lbl):
640                        lbl = lbl[panelcount]
641                    else:
642                        # get default label
643                        lbl = self._get_label(scan, r, self._panelling, None)
644                self._plotter.set_axes('title',lbl)
645                newpanel = True
646                stackcount =0
647                panelcount += 1
648            if (b > b0 or newpanel) and stackcount < nstack:
649                y = []
650                if len(polmodes):
651                    y = scan._getspectrum(r, polmodes[scan.getpol(r)])
652                else:
653                    y = scan._getspectrum(r)
654                m = scan._getmask(r)
655                from matplotlib.numerix import logical_not, logical_and
656                if self._maskselection and len(self._usermask) == len(m):
657                    if d[self._stacking](r) in self._maskselection[self._stacking]:
658                        m = logical_and(m, self._usermask)
659                x = scan._getabcissa(r)
660                from matplotlib.numerix import ma, array
661                y = ma.masked_array(y,mask=logical_not(array(m,copy=False)))
662                if self._minmaxx is not None:
663                    s,e = self._slice_indeces(x)
664                    x = x[s:e]
665                    y = y[s:e]
666                if len(x) > 1024 and rcParams['plotter.decimate']:
667                    fac = len(x)/1024
668                    x = x[::fac]
669                    y = y[::fac]
670                llbl = self._get_label(scan, r, self._stacking, self._lmap)
671                if isinstance(llbl, list) or isinstance(llbl, tuple):
672                    if 0 <= stackcount < len(llbl):
673                        # use user label
674                        llbl = llbl[stackcount]
675                    else:
676                        # get default label
677                        llbl = self._get_label(scan, r, self._stacking, None)
678                self._plotter.set_line(label=llbl)
679                plotit = self._plotter.plot
680                if self._hist: plotit = self._plotter.hist
681                if len(x) > 0:
682                    plotit(x,y)
683                    xlim= self._minmaxx or [min(x),max(x)]
684                    allxlim += xlim
685                    ylim= self._minmaxy or [ma.minimum(y),ma.maximum(y)]
686                    allylim += ylim
687                stackcount += 1
688                # last in colour stack -> autoscale x
689                if stackcount == nstack:
690                    allxlim.sort()
691                    self._plotter.axes.set_xlim([allxlim[0],allxlim[-1]])
692                    # clear
693                    allxlim =[]
694
695            newpanel = False
696            a0=a
697            b0=b
698            # ignore following rows
699            if (panelcount == n) and (stackcount == nstack):
700                # last panel -> autoscale y if ganged
701                if rcParams['plotter.ganged']:
702                    allylim.sort()
703                    self._plotter.set_limits(ylim=[allylim[0],allylim[-1]])
704                break
705            r+=1 # next row
706        #reset the selector to the scantable's original
707        scan.set_selection(savesel)
708
709    def set_selection(self, selection=None, refresh=True):
710        self._selection = isinstance(selection,selector) and selection or selector()
711        d0 = {'s': 'SCANNO', 'b': 'BEAMNO', 'i':'IFNO',
712              'p': 'POLNO', 'c': 'CYCLENO', 't' : 'TIME' }
713        order = [d0[self._panelling],d0[self._stacking]]
714        self._selection.set_order(order)
715        if self._data and refresh: self.plot(self._data)
716
717    def _get_selected_n(self, scan):
718        d1 = {'b': scan.getbeamnos, 's': scan.getscannos,
719             'i': scan.getifnos, 'p': scan.getpolnos, 't': scan.ncycle }
720        d2 = { 'b': self._selection.get_beams(),
721               's': self._selection.get_scans(),
722               'i': self._selection.get_ifs(),
723               'p': self._selection.get_pols(),
724               't': self._selection.get_cycles() }
725        n =  d2[self._panelling] or d1[self._panelling]()
726        nstack = d2[self._stacking] or d1[self._stacking]()
727        return n,nstack
728
729    def _get_label(self, scan, row, mode, userlabel=None):
730        if isinstance(userlabel, list) and len(userlabel) == 0:
731            userlabel = " "
732        pms = dict(zip(self._selection.get_pols(),self._selection.get_poltypes()))
733        if len(pms):
734            poleval = scan._getpollabel(scan.getpol(row),pms[scan.getpol(row)])
735        else:
736            poleval = scan._getpollabel(scan.getpol(row),scan.poltype())
737        d = {'b': "Beam "+str(scan.getbeam(row)),
738             's': scan._getsourcename(row),
739             'i': "IF"+str(scan.getif(row)),
740             'p': poleval,
741             't': str(scan.get_time(row)) }
742        return userlabel or d[mode]
743
Note: See TracBrowser for help on using the repository browser.