source: trunk/python/asapplotter.py @ 377

Last change on this file since 377 was 377, checked in by mar637, 19 years ago
  • added user controlled set_layout
  • added save
  • added help for set_mode
  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 13.7 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)
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)
154        i = 0
155        for scan in scans:
156            if n > 1:
157                self._plotter.subplot(i)
158                self._plotter.palette(0)
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                self._plotter.set_panels(rows=n,cols=0)
209        for i in range(n):
210            if n>1:
211                self._plotter.subplot(i)
212                self._plotter.palette(0)
213            k=0
214            j=i
215            eval(cdict.get(self._panels))
216            for j in range(ncol):
217                if colmode == 's':
218                    scan = eval(cdict.get(colmode))
219                elif colmode == 't':
220                    k = j
221                else:
222                    eval(cdict.get(colmode))
223                x = None
224                y = None
225                m = None
226                x,xlab = scan.get_abcissa(k)
227                if self._abcissa: xlab = self._abcissa
228                y = scan._getspectrum(k)
229                if self._ordinate:
230                    ylab = self._ordinate
231                else:
232                    ylab = 'Flux ('+scan.get_fluxunit()+')'
233                m = scan._getmask(k)
234                if colmode == 's' or colmode == 't':
235                    if not self._title:
236                        tlab = self._ldict.get(self._panels)+' '+str(i)
237                    else:
238                        if len(self.title) == n:
239                            tlab = self._title[i]
240                        else:
241                            tlab = self._ldict.get(self._panels)+' '+str(i)
242                    llab = scan._getsourcename(k)
243                else:
244                    if self._title and len(self._title) > 0:
245                        tlab = self._title[i]
246                    else:
247                        tlab = self._ldict.get(self._panels)+' '+str(i)
248                    if self._lmap and len(self._lmap) > 0:
249                        llab = self._lmap[j]
250                    else:
251                        llab = self._ldict.get(colmode)+' '+str(j)
252                self._plotter.set_line(label=llab)
253                self._plotter.plot(x,y,m)
254                xlim=[min(x),max(x)]
255                self._plotter.axes.set_xlim(xlim)
256
257            self._plotter.set_axes('xlabel',xlab)
258            self._plotter.set_axes('ylabel',ylab)
259            self._plotter.set_axes('title',tlab)
260       
261        return
262
263
264    def set_mode(self, stacking=None, panelling=None):
265        """
266        Set the plots look and feel, i.e. what you want to see on the plot.
267        Parameters:
268            stacking:     tell the plotter which variable to plot
269                          as line colour overlays (default 'pol')
270            panelling:    tell the plotter which variable to plot
271                          across multiple panels (default 'scan'
272        Note:
273            Valid modes are:
274                 'beam' 'Beam' 'b':     Beams
275                 'if' 'IF' 'i':         IFs
276                 'pol' 'Pol' 'p':       Polarisations
277                 'scan' 'Scan' 's':     Scans
278                 'time' 'Time' 't':     Times
279        """
280        if not self.set_panels(panelling):
281            print "Invalid mode"
282            return
283        if not self.set_stacking(stacking):
284            print "Invalid mode"
285            return
286        if self._data: self.plot()
287        return
288
289    def set_panels(self, what=None):
290        """       
291        """
292        if not what:
293             what = rcParams['plotter.panelling']
294        md = self._translate(what)
295        if md:
296            self._panels = md
297            self._title = None
298            return True
299        return False
300
301    def set_layout(self,rows=None,cols=None):
302        """
303        Set the multi-panel layout, i.e. how many rows and columns plots
304        are visible.
305        Parameters:
306             rows:   The number of rows of plots
307             cols:   The number of columns of plots
308        Note:
309             If no argument is given, the potter reverts to its auto-plot
310             behaviour.
311        """
312        self._rows = rows
313        self._cols = cols
314        if self._data: self.plot()
315        return
316
317    def set_stacking(self, what=None): 
318        if not what:
319             what = rcParams['plotter.stacking']       
320        md = self._translate(what)
321        if md:
322            self._stacking = md
323            self._lmap = None
324            return True
325        return False
326
327    def set_range(self,start=None,end=None):
328        """
329        Set the range of interest on the abcissa of the plot
330        Parameters:
331            start,end:    The start an end point of the 'zoom' window
332        Note:
333            These become non-sensical when the unit changes.
334            use plotter.set_range() without parameters to reset
335
336        """
337        if start is None and end is None:
338            self._minmax = None
339            if self._data: self.plot()
340        else:
341            self._minmax = [start,end]
342            if self._data: self.plot()
343        return
344   
345    def set_legend(self, mp=None):
346        """
347        Specify a mapping for the legend instead of using the default
348        indices:
349        Parameters:
350             mp:    a list of 'strings'. This should have the same length
351                    as the number of elements on the legend and then maps
352                    to the indeces in order
353
354        Example:
355             If the data has to IFs/rest frequencies with index 0 and 1
356             for CO and SiO:
357             plotter.set_stacking('i')
358             plotter.set_legend_map(['CO','SiO'])
359             plotter.plot()
360        """
361        self._lmap = mp
362        if self._data: self.plot()
363        return
364
365    def set_title(self, title=None):
366        self._title = title
367        if self._data: self.plot()
368        return
369
370    def set_ordinate(self, ordinate=None):
371        self._ordinate = ordinate
372        if self._data: self.plot()
373        return
374
375    def set_abcissa(self, abcissa=None):
376        self._abcissa = abcissa
377        if self._data: self.plot()
378        return
379
380    def save(self, filename=None):
381        """
382        Save the plot to a file. The know formats are 'png', 'ps', 'eps'.
383        Parameters:
384             filename:    The name of the output file. This is optional
385                          and autodetects the image format from the file
386                          suffix. If non filename is specified a file
387                          called 'yyyymmdd_hhmmss.png' is created in the
388                          current directory.
389        """
390        self._plotter.save(filename)
391        return
392
393if __name__ == '__main__':
394    plotter = asapplotter()
Note: See TracBrowser for help on using the repository browser.