source: trunk/python/asapplotter.py @ 485

Last change on this file since 485 was 485, checked in by mar637, 19 years ago

minor bug fixes

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 13.8 KB
Line 
1from asap.asaplot import ASAPlot
2from asap import rcParams
3
4class asapplotter:
5    """
6    The ASAP plotter.
7    By default the plotter is set up to plot polarisations
8    'colour stacked' and scantables across panels.
9    Note:
10        Currenly it only plots 'spectra' not Tsys or
11        other variables.
12    """
13    def __init__(self):
14        self._plotter = ASAPlot()
15
16        self._tdict = {'Time':'t','time':'t','t':'t','T':'t'}
17        self._bdict = {'Beam':'b','beam':'b','b':'b','B':'b'}
18        self._idict = {'IF':'i','if':'i','i':'i','I':'i'}
19        self._pdict = {'Pol':'p','pol':'p','p':'p'}
20        self._sdict = {'scan':'s','Scan':'s','s':'s','S':'s'}
21        self._cdict = {'t':'scan.nrow()',
22                       'b':'scan.nbeam()',
23                       'i':'scan.nif()',
24                       'p':'scan.npol()',
25                       's':'len(scans)'}
26        self._ldict = {'b':'Beam',
27                       'i':'IF',
28                       'p':'Pol',
29                       's':'Scan'}
30        self._dicts = [self._tdict,self._bdict,
31                       self._idict,self._pdict,
32                       self._sdict]
33        self._panels = 's'
34        self._stacking = rcParams['plotter.stacking']
35        self._rows = None
36        self._cols = None
37        self._autoplot = False
38        self._minmax = None
39        self._data = None
40        self._lmap = []
41        self._title = None
42        self._ordinate = None
43        self._abcissa = None
44
45    def _translate(self, name):
46        for d in self._dicts:
47            if d.has_key(name):
48                return d[name]
49        return None
50       
51    def plot(self,*args):
52        """
53        Plot a (list of) scantables.
54        Parameters:
55            one or more comma separated scantables
56        Note:
57            If a (list) of scantables was specified in a previous call
58            to plot, no argument has to be given to 'replot'
59            NO checking is done that the abscissas of the scantables
60            are consistent e.g. all 'channel' or all 'velocity' etc.
61        """
62        if self._plotter.is_dead:
63            self._plotter = ASAPlot()
64        self._plotter.clear()
65        self._plotter.hold()
66        if len(args) > 0:
67            self._data = tuple(args)           
68        if self._panels == 't':
69            if self._data[0].nrow() > 25:
70                print "Scan to be plotted contains more than 25 rows.\nCan't plot that many panels..."
71                return
72            self._plot_time(self._data[0], self._stacking)
73        elif self._panels == 's':
74            self._plot_scans(self._data, self._stacking)
75        else:
76            self._plot_other(self._data, self._stacking)
77        if self._minmax is not None:
78            self._plotter.set_limits(xlim=self._minmax)
79        self._plotter.release()
80        return
81
82    def _plot_time(self, scan, colmode):
83        if colmode == 't':
84            return
85        n = scan.nrow()
86        cdict = {'b':'scan.setbeam(j)',
87                 'i':'scan.setif(j)',
88                 'p':'scan.setpol(j)'}
89        if self._stacking is not None:
90            ncol = eval(self._cdict.get(colmode))
91        self._plotter.set_panels()
92        if n > 1:
93            if self._rows and self._cols:
94                n = min(n,self._rows*self._cols)
95                self._plotter.set_panels(rows=self._rows,cols=self._cols,
96                                         nplots=n)
97            else:
98                self._plotter.set_panels(rows=n,cols=0,nplots=n)
99        for i in range(n):
100            if n > 1:
101                self._plotter.palette(1)
102                self._plotter.subplot(i)
103            for j in range(ncol):
104                eval(cdict.get(colmode))
105                x = None
106                y = None
107                m = None
108                if not self._title:
109                    tlab = scan._getsourcename(i)                   
110                else:
111                    if len(self._title) == n:
112                        tlab = self._title[i]
113                    else:
114                        tlab = scan._getsourcename(i)                   
115                x,xlab = scan.get_abcissa(i)
116                if self._abcissa: xlab = self._abcissa
117                y = scan._getspectrum(i)
118                if self._ordinate:
119                    ylab = self._ordinate
120                else:
121                    ylab = 'Flux ('+scan.get_fluxunit()+')'
122                m = scan._getmask(i)
123                if self._lmap and len(self._lmap) > 0:
124                    llab = self._lmap[j]
125                else:
126                    llab = self._ldict.get(colmode)+' '+str(j)
127                self._plotter.set_line(label=llab)
128                self._plotter.plot(x,y,m)
129                xlim=[min(x),max(x)]
130                self._plotter.axes.set_xlim(xlim)
131            self._plotter.set_axes('xlabel',xlab)
132            self._plotter.set_axes('ylabel',ylab)
133            self._plotter.set_axes('title',tlab)           
134        return
135
136    def _plot_scans(self, scans, colmode):       
137        if colmode == 's':
138            return
139        cdict = {'b':'scan.setbeam(j)',
140                 'i':'scan.setif(j)',
141                 'p':'scan.setpol(j)'}
142        n = len(scans)
143        if self._stacking is not None:
144            scan = scans[0]
145            ncol = eval(self._cdict.get(colmode))
146        self._plotter.set_panels()
147        if n > 1:
148            if self._rows and self._cols:
149                n = min(n,self._rows*self._cols)
150                self._plotter.set_panels(rows=self._rows,cols=self._cols,
151                                         nplots=n)
152            else:
153                self._plotter.set_panels(rows=n,cols=0,nplots=n)
154        i = 0
155        for scan in scans:
156            if n > 1:
157                self._plotter.subplot(i)
158                self._plotter.palette(1)
159            for j in range(ncol):
160                eval(cdict.get(colmode))
161                x = None
162                y = None
163                m = None
164                tlab = self._title
165                if not self._title:
166                    tlab = scan._getsourcename()
167                x,xlab = scan.get_abcissa()
168                if self._abcissa: xlab = self._abcissa
169                y = scan._getspectrum()
170                if self._ordinate:
171                    ylab = self._ordinate
172                else:
173                    ylab = 'Flux ('+scan.get_fluxunit()+')'
174                m = scan._getmask()
175                if self._lmap and len(self._lmap) > 0:
176                    llab = self._lmap[j]
177                else:
178                    llab = self._ldict.get(colmode)+' '+str(j)
179                self._plotter.set_line(label=llab)
180                self._plotter.plot(x,y,m)
181                xlim=[min(x),max(x)]
182                self._plotter.axes.set_xlim(xlim)
183
184            self._plotter.set_axes('xlabel',xlab)
185            self._plotter.set_axes('ylabel',ylab)
186            self._plotter.set_axes('title',tlab)
187            i += 1
188        return
189   
190    def _plot_other(self,scans,colmode):
191        if colmode == self._panels:
192            return
193        cdict = {'b':'scan.setbeam(j)',
194                 'i':'scan.setif(j)',
195                 'p':'scan.setpol(j)',
196                 's':'scans[j]'}
197        scan = scans[0]
198        n = eval(self._cdict.get(self._panels))
199        if self._stacking is not None:           
200            ncol = eval(self._cdict.get(colmode))
201        self._plotter.set_panels()
202        if n > 1:
203            if self._rows and self._cols:
204                n = min(n,self._rows*self._cols)
205                self._plotter.set_panels(rows=self._rows,cols=self._cols,
206                                         nplots=n)
207            else:
208                print n
209                self._plotter.set_panels(rows=n,cols=0,nplots=n)
210        for i in range(n):
211            if n>1:
212                self._plotter.subplot(i)
213                self._plotter.palette(1)
214            k=0
215            j=i
216            eval(cdict.get(self._panels))
217            for j in range(ncol):
218                if colmode == 's':
219                    scan = eval(cdict.get(colmode))
220                elif colmode == 't':
221                    k = j
222                else:
223                    eval(cdict.get(colmode))
224                x = None
225                y = None
226                m = None
227                x,xlab = scan.get_abcissa(k)
228                if self._abcissa: xlab = self._abcissa
229                y = scan._getspectrum(k)
230                if self._ordinate:
231                    ylab = self._ordinate
232                else:
233                    ylab = 'Flux ('+scan.get_fluxunit()+')'
234                m = scan._getmask(k)
235                if colmode == 's' or colmode == 't':
236                    if not self._title:
237                        tlab = self._ldict.get(self._panels)+' '+str(i)
238                    else:
239                        if len(self.title) == n:
240                            tlab = self._title[i]
241                        else:
242                            tlab = self._ldict.get(self._panels)+' '+str(i)
243                    llab = scan._getsourcename(k)
244                else:
245                    if self._title and len(self._title) > 0:
246                        tlab = self._title[i]
247                    else:
248                        tlab = self._ldict.get(self._panels)+' '+str(i)
249                    if self._lmap and len(self._lmap) > 0:
250                        llab = self._lmap[j]
251                    else:
252                        llab = self._ldict.get(colmode)+' '+str(j)
253                self._plotter.set_line(label=llab)
254                self._plotter.plot(x,y,m)
255                xlim=[min(x),max(x)]
256                self._plotter.axes.set_xlim(xlim)
257
258            self._plotter.set_axes('xlabel',xlab)
259            self._plotter.set_axes('ylabel',ylab)
260            self._plotter.set_axes('title',tlab)
261       
262        return
263
264
265    def set_mode(self, stacking=None, panelling=None):
266        """
267        Set the plots look and feel, i.e. what you want to see on the plot.
268        Parameters:
269            stacking:     tell the plotter which variable to plot
270                          as line colour overlays (default 'pol')
271            panelling:    tell the plotter which variable to plot
272                          across multiple panels (default 'scan'
273        Note:
274            Valid modes are:
275                 'beam' 'Beam' 'b':     Beams
276                 'if' 'IF' 'i':         IFs
277                 'pol' 'Pol' 'p':       Polarisations
278                 'scan' 'Scan' 's':     Scans
279                 'time' 'Time' 't':     Times
280        """
281        if not self.set_panels(panelling):
282            print "Invalid mode"
283            return
284        if not self.set_stacking(stacking):
285            print "Invalid mode"
286            return
287        if self._data: self.plot()
288        return
289
290    def set_panels(self, what=None):
291        """       
292        """
293        if not what:
294             what = rcParams['plotter.panelling']
295        md = self._translate(what)
296        if md:
297            self._panels = md
298            self._title = None
299            return True
300        return False
301
302    def set_layout(self,rows=None,cols=None):
303        """
304        Set the multi-panel layout, i.e. how many rows and columns plots
305        are visible.
306        Parameters:
307             rows:   The number of rows of plots
308             cols:   The number of columns of plots
309        Note:
310             If no argument is given, the potter reverts to its auto-plot
311             behaviour.
312        """
313        self._rows = rows
314        self._cols = cols
315        if self._data: self.plot()
316        return
317
318    def set_stacking(self, what=None): 
319        if not what:
320             what = rcParams['plotter.stacking']       
321        md = self._translate(what)
322        if md:
323            self._stacking = md
324            self._lmap = None
325            return True
326        return False
327
328    def set_range(self,start=None,end=None):
329        """
330        Set the range of interest on the abcissa of the plot
331        Parameters:
332            start,end:    The start an end point of the 'zoom' window
333        Note:
334            These become non-sensical when the unit changes.
335            use plotter.set_range() without parameters to reset
336
337        """
338        if start is None and end is None:
339            self._minmax = None
340            if self._data: self.plot()
341        else:
342            self._minmax = [start,end]
343            if self._data: self.plot()
344        return
345   
346    def set_legend(self, mp=None):
347        """
348        Specify a mapping for the legend instead of using the default
349        indices:
350        Parameters:
351             mp:    a list of 'strings'. This should have the same length
352                    as the number of elements on the legend and then maps
353                    to the indeces in order
354
355        Example:
356             If the data has two IFs/rest frequencies with index 0 and 1
357             for CO and SiO:
358             plotter.set_stacking('i')
359             plotter.set_legend_map(['CO','SiO'])
360             plotter.plot()
361        """
362        self._lmap = mp
363        if self._data: self.plot()
364        return
365
366    def set_title(self, title=None):
367        self._title = title
368        if self._data: self.plot()
369        return
370
371    def set_ordinate(self, ordinate=None):
372        self._ordinate = ordinate
373        if self._data: self.plot()
374        return
375
376    def set_abcissa(self, abcissa=None):
377        self._abcissa = abcissa
378        if self._data: self.plot()
379        return
380
381    def save(self, filename=None):
382        """
383        Save the plot to a file. The know formats are 'png', 'ps', 'eps'.
384        Parameters:
385             filename:    The name of the output file. This is optional
386                          and autodetects the image format from the file
387                          suffix. If non filename is specified a file
388                          called 'yyyymmdd_hhmmss.png' is created in the
389                          current directory.
390        """
391        self._plotter.save(filename)
392        return
393
394if __name__ == '__main__':
395    plotter = asapplotter()
Note: See TracBrowser for help on using the repository browser.