source: trunk/python/asapplotter.py@ 434

Last change on this file since 434 was 377, checked in by mar637, 20 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
RevLine 
[203]1from asap.asaplot import ASAPlot
[226]2from asap import rcParams
[203]3
4class asapplotter:
[226]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 """
[203]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'
[226]34 self._stacking = rcParams['plotter.stacking']
[377]35 self._rows = None
36 self._cols = None
[203]37 self._autoplot = False
38 self._minmax = None
39 self._data = None
40 self._lmap = []
[226]41 self._title = None
[257]42 self._ordinate = None
43 self._abcissa = None
[203]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:
[377]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)
[203]99 for i in range(n):
100 if n > 1:
[377]101 self._plotter.palette(1)
[203]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
[226]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)
[203]115 x,xlab = scan.get_abcissa(i)
[257]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)
[226]123 if self._lmap and len(self._lmap) > 0:
[203]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:
[377]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)
[203]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
[226]164 tlab = self._title
165 if not self._title:
166 tlab = scan._getsourcename()
[203]167 x,xlab = scan.get_abcissa()
[257]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:
[203]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:
[377]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)
[203]209 for i in range(n):
210 if n>1:
211 self._plotter.subplot(i)
212 self._plotter.palette(0)
213 k=0
[282]214 j=i
[203]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)
[257]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)
[203]234 if colmode == 's' or colmode == 't':
[226]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)
[203]242 llab = scan._getsourcename(k)
243 else:
[226]244 if self._title and len(self._title) > 0:
[257]245 tlab = self._title[i]
[226]246 else:
[257]247 tlab = self._ldict.get(self._panels)+' '+str(i)
[226]248 if self._lmap and len(self._lmap) > 0:
[203]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
[226]264 def set_mode(self, stacking=None, panelling=None):
[203]265 """
[377]266 Set the plots look and feel, i.e. what you want to see on the plot.
[203]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"
[226]282 return
[203]283 if not self.set_stacking(stacking):
284 print "Invalid mode"
[226]285 return
286 if self._data: self.plot()
[203]287 return
288
[377]289 def set_panels(self, what=None):
290 """
291 """
[226]292 if not what:
293 what = rcParams['plotter.panelling']
[203]294 md = self._translate(what)
295 if md:
[226]296 self._panels = md
297 self._title = None
[203]298 return True
299 return False
300
[377]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
[226]317 def set_stacking(self, what=None):
318 if not what:
319 what = rcParams['plotter.stacking']
[203]320 md = self._translate(what)
321 if md:
322 self._stacking = md
[226]323 self._lmap = None
[203]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
[226]339 if self._data: self.plot()
[203]340 else:
341 self._minmax = [start,end]
[226]342 if self._data: self.plot()
[203]343 return
344
[257]345 def set_legend(self, mp=None):
[203]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
[226]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
[257]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
[377]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
[257]392
[203]393if __name__ == '__main__':
394 plotter = asapplotter()
Note: See TracBrowser for help on using the repository browser.