source: trunk/python/asapplotter.py@ 495

Last change on this file since 495 was 485, checked in by mar637, 20 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.