source: branches/polybatch/python/asapplotter.py@ 2646

Last change on this file since 2646 was 1913, checked in by Kana Sugimoto, 14 years ago

New Development: Yes

JIRA Issue: Yes (CAS-1822)

Ready for Test: Yes

Interface Changes: Yes

What Interface Changed: added "- page" (inactive) and "+ page" buttons to the toolbar

Test Programs: try "+ page" button

Put in Release Notes: Yes

Module(s): asapplotter & sdplot

Description:

  1. "- page" (inactive) and "+ page" buttons to the toolbar to enable

multi-page plotting. Currently "+ page" is only supported.

  1. Enabled row panelling and stacking. Note that only single stack/panel

is plotted when row panneling/stacking is selected.


  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 53.9 KB
Line 
1from asap.parameters import rcParams
2from asap.selector import selector
3from asap.scantable import scantable
4from asap.logging import asaplog, asaplog_post_dec
5import matplotlib.axes
6from matplotlib.font_manager import FontProperties
7from matplotlib.text import Text
8
9import re
10
11class asapplotter:
12 """
13 The ASAP plotter.
14 By default the plotter is set up to plot polarisations
15 'colour stacked' and scantables across panels.
16
17 .. note::
18
19 Currenly it only plots 'spectra' not Tsys or
20 other variables.
21
22 """
23 def __init__(self, visible=None , **kwargs):
24 self._visible = rcParams['plotter.gui']
25 if visible is not None:
26 self._visible = visible
27 self._plotter = self._newplotter(**kwargs)
28 # additional tool bar
29 self._plotter.figmgr.casabar=self._newcasabar()
30
31 self._panelling = None
32 self._stacking = None
33 self.set_panelling()
34 self.set_stacking()
35 self._rows = None
36 self._cols = None
37 self._autoplot = False
38 self._minmaxx = None
39 self._minmaxy = None
40 self._datamask = None
41 self._data = None
42 self._lmap = None
43 self._title = None
44 self._ordinate = None
45 self._abcissa = None
46 self._abcunit = None
47 self._usermask = []
48 self._maskselection = None
49 self._selection = selector()
50 self._hist = rcParams['plotter.histogram']
51 self._fp = FontProperties()
52 self._panellayout = self.set_panellayout(refresh=False)
53 self._offset = None
54 self._rowcount = 0
55 self._panelcnt = 0
56
57 def _translate(self, instr):
58 keys = "s b i p t r".split()
59 if isinstance(instr, str):
60 for key in keys:
61 if instr.lower().startswith(key):
62 return key
63 return None
64
65 def _newplotter(self, **kwargs):
66 backend=matplotlib.get_backend()
67 if not self._visible:
68 from asap.asaplot import asaplot
69 elif backend == 'TkAgg':
70 from asap.asaplotgui import asaplotgui as asaplot
71 elif backend == 'Qt4Agg':
72 from asap.asaplotgui_qt4 import asaplotgui as asaplot
73 elif backend == 'GTkAgg':
74 from asap.asaplotgui_gtk import asaplotgui as asaplot
75 else:
76 from asap.asaplot import asaplot
77 return asaplot(**kwargs)
78
79 def _newcasabar(self):
80 backend=matplotlib.get_backend()
81 if self._visible and backend == "TkAgg":
82 from asap.casatoolbar import CustomToolbarTkAgg
83 return CustomToolbarTkAgg(self)
84 else: return None
85
86 @asaplog_post_dec
87 def plot(self, scan=None):
88 """
89 Plot a scantable.
90 Parameters:
91 scan: a scantable
92 Note:
93 If a scantable was specified in a previous call
94 to plot, no argument has to be given to 'replot'
95 NO checking is done that the abcissas of the scantable
96 are consistent e.g. all 'channel' or all 'velocity' etc.
97 """
98 self._rowcount = self._panelcnt = 0
99 if self._plotter.is_dead:
100 if hasattr(self._plotter.figmgr,'casabar'):
101 del self._plotter.figmgr.casabar
102 self._plotter = self._newplotter()
103 self._plotter.figmgr.casabar=self._newcasabar()
104 self._plotter.hold()
105 self._plotter.clear()
106 if not self._data and not scan:
107 msg = "Input is not a scantable"
108 raise TypeError(msg)
109 if scan:
110 self.set_data(scan, refresh=False)
111 self._plot(self._data)
112 if self._minmaxy is not None:
113 self._plotter.set_limits(ylim=self._minmaxy)
114 if self._plotter.figmgr.casabar: self._plotter.figmgr.casabar.enable_button()
115 self._plotter.release()
116 self._plotter.tidy()
117 self._plotter.show(hardrefresh=False)
118 return
119
120 def gca(self):
121 return self._plotter.figure.gca()
122
123 def refresh(self):
124 """Do a soft refresh"""
125 self._plotter.figure.show()
126
127 def create_mask(self, nwin=1, panel=0, color=None):
128 """
129 Interactively define a mask.It retruns a mask that is equivalent to
130 the one created manually with scantable.create_mask.
131 Parameters:
132 nwin: The number of mask windows to create interactively
133 default is 1.
134 panel: Which panel to use for mask selection. This is useful
135 if different IFs are spread over panels (default 0)
136 """
137 if self._data is None:
138 return []
139 outmask = []
140 self._plotter.subplot(panel)
141 xmin, xmax = self._plotter.axes.get_xlim()
142 marg = 0.05*(xmax-xmin)
143 self._plotter.axes.set_xlim(xmin-marg, xmax+marg)
144 self.refresh()
145
146 def cleanup(lines=False, texts=False, refresh=False):
147 if lines:
148 del self._plotter.axes.lines[-1]
149 if texts:
150 del self._plotter.axes.texts[-1]
151 if refresh:
152 self.refresh()
153
154 for w in xrange(nwin):
155 wpos = []
156 self.text(0.05,1.0, "Add start boundary",
157 coords="relative", fontsize=10)
158 point = self._plotter.get_point()
159 cleanup(texts=True)
160 if point is None:
161 continue
162 wpos.append(point[0])
163 self.axvline(wpos[0], color=color)
164 self.text(0.05,1.0, "Add end boundary", coords="relative", fontsize=10)
165 point = self._plotter.get_point()
166 cleanup(texts=True, lines=True)
167 if point is None:
168 self.refresh()
169 continue
170 wpos.append(point[0])
171 self.axvspan(wpos[0], wpos[1], alpha=0.1,
172 edgecolor=color, facecolor=color)
173 ymin, ymax = self._plotter.axes.get_ylim()
174 outmask.append(wpos)
175
176 self._plotter.axes.set_xlim(xmin, xmax)
177 self.refresh()
178 if len(outmask) > 0:
179 return self._data.create_mask(*outmask)
180 return []
181
182 # forwards to matplotlib axes
183 def text(self, *args, **kwargs):
184 if kwargs.has_key("interactive"):
185 if kwargs.pop("interactive"):
186 pos = self._plotter.get_point()
187 args = tuple(pos)+args
188 self._axes_callback("text", *args, **kwargs)
189
190 text.__doc__ = matplotlib.axes.Axes.text.__doc__
191
192 def arrow(self, *args, **kwargs):
193 if kwargs.has_key("interactive"):
194 if kwargs.pop("interactive"):
195 pos = self._plotter.get_region()
196 dpos = (pos[0][0], pos[0][1],
197 pos[1][0]-pos[0][0],
198 pos[1][1] - pos[0][1])
199 args = dpos + args
200 self._axes_callback("arrow", *args, **kwargs)
201
202 arrow.__doc__ = matplotlib.axes.Axes.arrow.__doc__
203
204 def annotate(self, text, xy=None, xytext=None, **kwargs):
205 if kwargs.has_key("interactive"):
206 if kwargs.pop("interactive"):
207 xy = self._plotter.get_point()
208 xytext = self._plotter.get_point()
209 if not kwargs.has_key("arrowprops"):
210 kwargs["arrowprops"] = dict(arrowstyle="->")
211 self._axes_callback("annotate", text, xy, xytext, **kwargs)
212
213 annotate.__doc__ = matplotlib.axes.Axes.annotate.__doc__
214
215 def axvline(self, *args, **kwargs):
216 if kwargs.has_key("interactive"):
217 if kwargs.pop("interactive"):
218 pos = self._plotter.get_point()
219 args = (pos[0],)+args
220 self._axes_callback("axvline", *args, **kwargs)
221
222 axvline.__doc__ = matplotlib.axes.Axes.axvline.__doc__
223
224 def axhline(self, *args, **kwargs):
225 if kwargs.has_key("interactive"):
226 if kwargs.pop("interactive"):
227 pos = self._plotter.get_point()
228 args = (pos[1],)+args
229 self._axes_callback("axhline", *args, **kwargs)
230
231 axhline.__doc__ = matplotlib.axes.Axes.axhline.__doc__
232
233 def axvspan(self, *args, **kwargs):
234 if kwargs.has_key("interactive"):
235 if kwargs.pop("interactive"):
236 pos = self._plotter.get_region()
237 dpos = (pos[0][0], pos[1][0])
238 args = dpos + args
239 self._axes_callback("axvspan", *args, **kwargs)
240 # hack to preventy mpl from redrawing the patch
241 # it seem to convert the patch into lines on every draw.
242 # This doesn't happen in a test script???
243 #del self._plotter.axes.patches[-1]
244
245 axvspan.__doc__ = matplotlib.axes.Axes.axvspan.__doc__
246
247 def axhspan(self, *args, **kwargs):
248 if kwargs.has_key("interactive"):
249 if kwargs.pop("interactive"):
250 pos = self._plotter.get_region()
251 dpos = (pos[0][1], pos[1][1])
252 args = dpos + args
253 self._axes_callback("axhspan", *args, **kwargs)
254 # hack to preventy mpl from redrawing the patch
255 # it seem to convert the patch into lines on every draw.
256 # This doesn't happen in a test script???
257 #del self._plotter.axes.patches[-1]
258
259 axhspan.__doc__ = matplotlib.axes.Axes.axhspan.__doc__
260
261 def _axes_callback(self, axesfunc, *args, **kwargs):
262 panel = 0
263 if kwargs.has_key("panel"):
264 panel = kwargs.pop("panel")
265 coords = None
266 if kwargs.has_key("coords"):
267 coords = kwargs.pop("coords")
268 if coords.lower() == 'world':
269 kwargs["transform"] = self._plotter.axes.transData
270 elif coords.lower() == 'relative':
271 kwargs["transform"] = self._plotter.axes.transAxes
272 self._plotter.subplot(panel)
273 self._plotter.axes.set_autoscale_on(False)
274 getattr(self._plotter.axes, axesfunc)(*args, **kwargs)
275 self._plotter.show(False)
276 self._plotter.axes.set_autoscale_on(True)
277 # end matplotlib.axes fowarding functions
278
279 @asaplog_post_dec
280 def set_data(self, scan, refresh=True):
281 """
282 Set a scantable to plot.
283 Parameters:
284 scan: a scantable
285 refresh: True (default) or False. If True, the plot is
286 replotted based on the new parameter setting(s).
287 Otherwise,the parameter(s) are set without replotting.
288 Note:
289 The user specified masks and data selections will be reset
290 if a new scantable is set. This method should be called before
291 setting data selections (set_selection) and/or masks (set_mask).
292 """
293 from asap import scantable
294 if isinstance(scan, scantable):
295 if self._data is not None:
296 if scan != self._data:
297 self._data = scan
298 # reset
299 self._reset()
300 msg = "A new scantable is set to the plotter. "\
301 "The masks and data selections are reset."
302 asaplog.push( msg )
303 else:
304 self._data = scan
305 self._reset()
306 else:
307 msg = "Input is not a scantable"
308 raise TypeError(msg)
309
310 # ranges become invalid when unit changes
311 if self._abcunit and self._abcunit != self._data.get_unit():
312 self._minmaxx = None
313 self._minmaxy = None
314 self._abcunit = self._data.get_unit()
315 self._datamask = None
316 if refresh: self.plot()
317
318 @asaplog_post_dec
319 def set_mode(self, stacking=None, panelling=None, refresh=True):
320 """
321 Set the plots look and feel, i.e. what you want to see on the plot.
322 Parameters:
323 stacking: tell the plotter which variable to plot
324 as line colour overlays (default 'pol')
325 panelling: tell the plotter which variable to plot
326 across multiple panels (default 'scan'
327 refresh: True (default) or False. If True, the plot is
328 replotted based on the new parameter setting(s).
329 Otherwise,the parameter(s) are set without replotting.
330 Note:
331 Valid modes are:
332 'beam' 'Beam' 'b': Beams
333 'if' 'IF' 'i': IFs
334 'pol' 'Pol' 'p': Polarisations
335 'scan' 'Scan' 's': Scans
336 'time' 'Time' 't': Times
337 """
338 msg = "Invalid mode"
339 if not self.set_panelling(panelling) or \
340 not self.set_stacking(stacking):
341 raise TypeError(msg)
342 if self._panelling == 'r':
343 self._stacking = '_r'
344 elif self._stacking == 'r':
345 self._panelling = '_r'
346 if refresh and self._data: self.plot(self._data)
347 return
348
349 def set_panelling(self, what=None):
350 """Set the 'panelling' mode i.e. which type of spectra should be
351 spread across different panels.
352 """
353
354 mode = what
355 if mode is None:
356 mode = rcParams['plotter.panelling']
357 md = self._translate(mode)
358 if md:
359 self._panelling = md
360 self._title = None
361 if md == 'r':
362 self._stacking = '_r'
363 return True
364 return False
365
366 def set_layout(self,rows=None,cols=None,refresh=True):
367 """
368 Set the multi-panel layout, i.e. how many rows and columns plots
369 are visible.
370 Parameters:
371 rows: The number of rows of plots
372 cols: The number of columns of plots
373 refresh: True (default) or False. If True, the plot is
374 replotted based on the new parameter setting(s).
375 Otherwise,the parameter(s) are set without replotting.
376 Note:
377 If no argument is given, the potter reverts to its auto-plot
378 behaviour.
379 """
380 self._rows = rows
381 self._cols = cols
382 if refresh and self._data: self.plot(self._data)
383 return
384
385 def set_stacking(self, what=None):
386 """Set the 'stacking' mode i.e. which type of spectra should be
387 overlayed.
388 """
389 mode = what
390 if mode is None:
391 mode = rcParams['plotter.stacking']
392 md = self._translate(mode)
393 if md:
394 self._stacking = md
395 self._lmap = None
396 if md == 'r':
397 self._panelling = '_r'
398 return True
399 return False
400
401 def set_range(self,xstart=None,xend=None,ystart=None,yend=None,refresh=True, offset=None):
402 """
403 Set the range of interest on the abcissa of the plot
404 Parameters:
405 [x,y]start,[x,y]end: The start and end points of the 'zoom' window
406 refresh: True (default) or False. If True, the plot is
407 replotted based on the new parameter setting(s).
408 Otherwise,the parameter(s) are set without replotting.
409 offset: shift the abcissa by the given amount. The abcissa label will
410 have '(relative)' appended to it.
411 Note:
412 These become non-sensical when the unit changes.
413 use plotter.set_range() without parameters to reset
414
415 """
416 self._offset = offset
417 if xstart is None and xend is None:
418 self._minmaxx = None
419 else:
420 self._minmaxx = [xstart,xend]
421 if ystart is None and yend is None:
422 self._minmaxy = None
423 else:
424 self._minmaxy = [ystart,yend]
425 if refresh and self._data: self.plot(self._data)
426 return
427
428 def set_legend(self, mp=None, fontsize = None, mode = 0, refresh=True):
429 """
430 Specify a mapping for the legend instead of using the default
431 indices:
432 Parameters:
433 mp: a list of 'strings'. This should have the same length
434 as the number of elements on the legend and then maps
435 to the indeces in order. It is possible to uses latex
436 math expression. These have to be enclosed in r'',
437 e.g. r'$x^{2}$'
438 fontsize: The font size of the label (default None)
439 mode: where to display the legend
440 Any other value for loc else disables the legend:
441 0: auto
442 1: upper right
443 2: upper left
444 3: lower left
445 4: lower right
446 5: right
447 6: center left
448 7: center right
449 8: lower center
450 9: upper center
451 10: center
452 refresh: True (default) or False. If True, the plot is
453 replotted based on the new parameter setting(s).
454 Otherwise,the parameter(s) are set without replotting.
455
456 Example:
457 If the data has two IFs/rest frequencies with index 0 and 1
458 for CO and SiO:
459 plotter.set_stacking('i')
460 plotter.set_legend(['CO','SiO'])
461 plotter.plot()
462 plotter.set_legend([r'$^{12}CO$', r'SiO'])
463 """
464 self._lmap = mp
465 self._plotter.legend(mode)
466 if isinstance(fontsize, int):
467 from matplotlib import rc as rcp
468 rcp('legend', fontsize=fontsize)
469 if refresh and self._data: self.plot(self._data)
470 return
471
472 def set_title(self, title=None, fontsize=None, refresh=True):
473 """
474 Set the title of the plot. If multiple panels are plotted,
475 multiple titles have to be specified.
476 Parameters:
477 refresh: True (default) or False. If True, the plot is
478 replotted based on the new parameter setting(s).
479 Otherwise,the parameter(s) are set without replotting.
480 Example:
481 # two panels are visible on the plotter
482 plotter.set_title(["First Panel","Second Panel"])
483 """
484 self._title = title
485 if isinstance(fontsize, int):
486 from matplotlib import rc as rcp
487 rcp('axes', titlesize=fontsize)
488 if refresh and self._data: self.plot(self._data)
489 return
490
491 def set_ordinate(self, ordinate=None, fontsize=None, refresh=True):
492 """
493 Set the y-axis label of the plot. If multiple panels are plotted,
494 multiple labels have to be specified.
495 Parameters:
496 ordinate: a list of ordinate labels. None (default) let
497 data determine the labels
498 refresh: True (default) or False. If True, the plot is
499 replotted based on the new parameter setting(s).
500 Otherwise,the parameter(s) are set without replotting.
501 Example:
502 # two panels are visible on the plotter
503 plotter.set_ordinate(["First Y-Axis","Second Y-Axis"])
504 """
505 self._ordinate = ordinate
506 if isinstance(fontsize, int):
507 from matplotlib import rc as rcp
508 rcp('axes', labelsize=fontsize)
509 rcp('ytick', labelsize=fontsize)
510 if refresh and self._data: self.plot(self._data)
511 return
512
513 def set_abcissa(self, abcissa=None, fontsize=None, refresh=True):
514 """
515 Set the x-axis label of the plot. If multiple panels are plotted,
516 multiple labels have to be specified.
517 Parameters:
518 abcissa: a list of abcissa labels. None (default) let
519 data determine the labels
520 refresh: True (default) or False. If True, the plot is
521 replotted based on the new parameter setting(s).
522 Otherwise,the parameter(s) are set without replotting.
523 Example:
524 # two panels are visible on the plotter
525 plotter.set_ordinate(["First X-Axis","Second X-Axis"])
526 """
527 self._abcissa = abcissa
528 if isinstance(fontsize, int):
529 from matplotlib import rc as rcp
530 rcp('axes', labelsize=fontsize)
531 rcp('xtick', labelsize=fontsize)
532 if refresh and self._data: self.plot(self._data)
533 return
534
535 def set_colors(self, colmap, refresh=True):
536 """
537 Set the colours to be used. The plotter will cycle through
538 these colours when lines are overlaid (stacking mode).
539 Parameters:
540 colmap: a list of colour names
541 refresh: True (default) or False. If True, the plot is
542 replotted based on the new parameter setting(s).
543 Otherwise,the parameter(s) are set without replotting.
544 Example:
545 plotter.set_colors("red green blue")
546 # If for example four lines are overlaid e.g I Q U V
547 # 'I' will be 'red', 'Q' will be 'green', U will be 'blue'
548 # and 'V' will be 'red' again.
549 """
550 if isinstance(colmap,str):
551 colmap = colmap.split()
552 self._plotter.palette(0, colormap=colmap)
553 if refresh and self._data: self.plot(self._data)
554
555 # alias for english speakers
556 set_colours = set_colors
557
558 def set_histogram(self, hist=True, linewidth=None, refresh=True):
559 """
560 Enable/Disable histogram-like plotting.
561 Parameters:
562 hist: True (default) or False. The fisrt default
563 is taken from the .asaprc setting
564 plotter.histogram
565 refresh: True (default) or False. If True, the plot is
566 replotted based on the new parameter setting(s).
567 Otherwise,the parameter(s) are set without replotting.
568 """
569 self._hist = hist
570 if isinstance(linewidth, float) or isinstance(linewidth, int):
571 from matplotlib import rc as rcp
572 rcp('lines', linewidth=linewidth)
573 if refresh and self._data: self.plot(self._data)
574
575 def set_linestyles(self, linestyles=None, linewidth=None, refresh=True):
576 """
577 Set the linestyles to be used. The plotter will cycle through
578 these linestyles when lines are overlaid (stacking mode) AND
579 only one color has been set.
580 Parameters:
581 linestyles: a list of linestyles to use.
582 'line', 'dashed', 'dotted', 'dashdot',
583 'dashdotdot' and 'dashdashdot' are
584 possible
585 refresh: True (default) or False. If True, the plot is
586 replotted based on the new parameter setting(s).
587 Otherwise,the parameter(s) are set without replotting.
588 Example:
589 plotter.set_colors("black")
590 plotter.set_linestyles("line dashed dotted dashdot")
591 # If for example four lines are overlaid e.g I Q U V
592 # 'I' will be 'solid', 'Q' will be 'dashed',
593 # U will be 'dotted' and 'V' will be 'dashdot'.
594 """
595 if isinstance(linestyles,str):
596 linestyles = linestyles.split()
597 self._plotter.palette(color=0,linestyle=0,linestyles=linestyles)
598 if isinstance(linewidth, float) or isinstance(linewidth, int):
599 from matplotlib import rc as rcp
600 rcp('lines', linewidth=linewidth)
601 if refresh and self._data: self.plot(self._data)
602
603 def set_font(self, refresh=True,**kwargs):
604 """
605 Set font properties.
606 Parameters:
607 family: one of 'sans-serif', 'serif', 'cursive', 'fantasy', 'monospace'
608 style: one of 'normal' (or 'roman'), 'italic' or 'oblique'
609 weight: one of 'normal or 'bold'
610 size: the 'general' font size, individual elements can be adjusted
611 seperately
612 refresh: True (default) or False. If True, the plot is
613 replotted based on the new parameter setting(s).
614 Otherwise,the parameter(s) are set without replotting.
615 """
616 from matplotlib import rc as rcp
617 fdict = {}
618 for k,v in kwargs.iteritems():
619 if v:
620 fdict[k] = v
621 self._fp = FontProperties(**fdict)
622 if refresh and self._data: self.plot(self._data)
623
624 def set_panellayout(self,layout=[],refresh=True):
625 """
626 Set the layout of subplots.
627 Parameters:
628 layout: a list of subplots layout in figure coordinate (0-1),
629 i.e., fraction of the figure width or height.
630 The order of elements should be:
631 [left, bottom, right, top, horizontal space btw panels,
632 vertical space btw panels].
633 refresh: True (default) or False. If True, the plot is
634 replotted based on the new parameter setting(s).
635 Otherwise,the parameter(s) are set without replotting.
636 Note
637 * When layout is not specified, the values are reset to the defaults
638 of matplotlib.
639 * If any element is set to be None, the current value is adopted.
640 """
641 if layout == []: self._panellayout=self._reset_panellayout()
642 else:
643 self._panellayout=[None]*6
644 self._panellayout[0:len(layout)]=layout
645 #print "panel layout set to ",self._panellayout
646 if refresh and self._data: self.plot(self._data)
647
648 def _reset_panellayout(self):
649 ks=map(lambda x: 'figure.subplot.'+x,
650 ['left','bottom','right','top','hspace','wspace'])
651 return map(matplotlib.rcParams.get,ks)
652
653 def plot_lines(self, linecat=None, doppler=0.0, deltachan=10, rotate=90.0,
654 location=None):
655 """
656 Plot a line catalog.
657 Parameters:
658 linecat: the linecatalog to plot
659 doppler: the velocity shift to apply to the frequencies
660 deltachan: the number of channels to include each side of the
661 line to determine a local maximum/minimum
662 rotate: the rotation (in degrees) )for the text label (default 90.0)
663 location: the location of the line annotation from the 'top',
664 'bottom' or alternate (None - the default)
665 Notes:
666 If the spectrum is flagged no line will be drawn in that location.
667 """
668 if not self._data:
669 raise RuntimeError("No scantable has been plotted yet.")
670 from asap._asap import linecatalog
671 if not isinstance(linecat, linecatalog):
672 raise ValueError("'linecat' isn't of type linecatalog.")
673 if not self._data.get_unit().endswith("Hz"):
674 raise RuntimeError("Can only overlay linecatalogs when data is in frequency.")
675 from numpy import ma
676 for j in range(len(self._plotter.subplots)):
677 self._plotter.subplot(j)
678 lims = self._plotter.axes.get_xlim()
679 for row in range(linecat.nrow()):
680 # get_frequency returns MHz
681 base = { "GHz": 1000.0, "MHz": 1.0, "Hz": 1.0e-6 }
682 restf = linecat.get_frequency(row)/base[self._data.get_unit()]
683 c = 299792.458
684 freq = restf*(1.0-doppler/c)
685 if lims[0] < freq < lims[1]:
686 if location is None:
687 loc = 'bottom'
688 if row%2: loc='top'
689 else: loc = location
690 maxys = []
691 for line in self._plotter.axes.lines:
692 v = line._x
693 asc = v[0] < v[-1]
694
695 idx = None
696 if not asc:
697 if v[len(v)-1] <= freq <= v[0]:
698 i = len(v)-1
699 while i>=0 and v[i] < freq:
700 idx = i
701 i-=1
702 else:
703 if v[0] <= freq <= v[len(v)-1]:
704 i = 0
705 while i<len(v) and v[i] < freq:
706 idx = i
707 i+=1
708 if idx is not None:
709 lower = idx - deltachan
710 upper = idx + deltachan
711 if lower < 0: lower = 0
712 if upper > len(v): upper = len(v)
713 s = slice(lower, upper)
714 y = line._y[s]
715 maxy = ma.maximum(y)
716 if isinstance( maxy, float):
717 maxys.append(maxy)
718 if len(maxys):
719 peak = max(maxys)
720 if peak > self._plotter.axes.get_ylim()[1]:
721 loc = 'bottom'
722 else:
723 continue
724 self._plotter.vline_with_label(freq, peak,
725 linecat.get_name(row),
726 location=loc, rotate=rotate)
727 self._plotter.show(hardrefresh=False)
728
729
730 def save(self, filename=None, orientation=None, dpi=None):
731 """
732 Save the plot to a file. The know formats are 'png', 'ps', 'eps'.
733 Parameters:
734 filename: The name of the output file. This is optional
735 and autodetects the image format from the file
736 suffix. If non filename is specified a file
737 called 'yyyymmdd_hhmmss.png' is created in the
738 current directory.
739 orientation: optional parameter for postscript only (not eps).
740 'landscape', 'portrait' or None (default) are valid.
741 If None is choosen for 'ps' output, the plot is
742 automatically oriented to fill the page.
743 dpi: The dpi of the output non-ps plot
744 """
745 self._plotter.save(filename,orientation,dpi)
746 return
747
748 @asaplog_post_dec
749 def set_mask(self, mask=None, selection=None, refresh=True):
750 """
751 Set a plotting mask for a specific polarization.
752 This is useful for masking out "noise" Pangle outside a source.
753 Parameters:
754 mask: a mask from scantable.create_mask
755 selection: the spectra to apply the mask to.
756 refresh: True (default) or False. If True, the plot is
757 replotted based on the new parameter setting(s).
758 Otherwise,the parameter(s) are set without replotting.
759 Example:
760 select = selector()
761 select.setpolstrings("Pangle")
762 plotter.set_mask(mymask, select)
763 """
764 if not self._data:
765 msg = "Can only set mask after a first call to plot()"
766 raise RuntimeError(msg)
767 if len(mask):
768 if isinstance(mask, list) or isinstance(mask, tuple):
769 self._usermask = array(mask)
770 else:
771 self._usermask = mask
772 if mask is None and selection is None:
773 self._usermask = []
774 self._maskselection = None
775 if isinstance(selection, selector):
776 self._maskselection = {'b': selection.get_beams(),
777 's': selection.get_scans(),
778 'i': selection.get_ifs(),
779 'p': selection.get_pols(),
780 't': [] }
781 else:
782 self._maskselection = None
783 if refresh: self.plot(self._data)
784
785 def _slice_indeces(self, data):
786 mn = self._minmaxx[0]
787 mx = self._minmaxx[1]
788 asc = data[0] < data[-1]
789 start=0
790 end = len(data)-1
791 inc = 1
792 if not asc:
793 start = len(data)-1
794 end = 0
795 inc = -1
796 # find min index
797 #while start > 0 and data[start] < mn:
798 # start+= inc
799 minind=start
800 for ind in xrange(start,end+inc,inc):
801 if data[ind] > mn: break
802 minind=ind
803 # find max index
804 #while end > 0 and data[end] > mx:
805 # end-=inc
806 #if end > 0: end +=1
807 maxind=end
808 for ind in xrange(end,start-inc,-inc):
809 if data[ind] < mx: break
810 maxind=ind
811 start=minind
812 end=maxind
813 if start > end:
814 return end,start+1
815 elif start < end:
816 return start,end+1
817 else:
818 return start,end
819
820 def _reset(self):
821 self._usermask = []
822 self._usermaskspectra = None
823 self._offset = None
824 self.set_selection(None, False)
825
826 def _plot(self, scan):
827 savesel = scan.get_selection()
828 sel = savesel + self._selection
829 order = self._get_sortstring([self._panelling,self._stacking])
830 if order:
831 sel.set_order(order)
832 scan.set_selection(sel)
833 d = {'b': scan.getbeam, 's': scan.getscan,
834 'i': scan.getif, 'p': scan.getpol, 't': scan._gettime,
835 'r': int, '_r': int}
836
837 polmodes = dict(zip(self._selection.get_pols(),
838 self._selection.get_poltypes()))
839 # this returns either a tuple of numbers or a length (ncycles)
840 # convert this into lengths
841 n0,nstack0 = self._get_selected_n(scan)
842 if isinstance(n0, int): n = n0
843 else: n = len(n0)
844 if isinstance(nstack0, int): nstack = nstack0
845 else: nstack = len(nstack0)
846 nptot = n
847 maxpanel, maxstack = 16,16
848 if nstack > maxstack:
849 msg ="Scan to be overlayed contains more than %d selections.\n" \
850 "Selecting first %d selections..." % (maxstack, maxstack)
851 asaplog.push(msg)
852 asaplog.post('WARN')
853 nstack = min(nstack,maxstack)
854 n = min(n,maxpanel)
855
856 if n > 1:
857 ganged = rcParams['plotter.ganged']
858 if self._panelling == 'i':
859 ganged = False
860 if self._rows and self._cols:
861 n = min(n,self._rows*self._cols)
862 self._plotter.set_panels(rows=self._rows,cols=self._cols,
863# nplots=n,ganged=ganged)
864 nplots=n,layout=self._panellayout,ganged=ganged)
865 else:
866# self._plotter.set_panels(rows=n,cols=0,nplots=n,ganged=ganged)
867 self._plotter.set_panels(rows=n,cols=0,nplots=n,layout=self._panellayout,ganged=ganged)
868 else:
869# self._plotter.set_panels()
870 self._plotter.set_panels(layout=self._panellayout)
871 #r = 0
872 r = self._rowcount
873 nr = scan.nrow()
874 a0,b0 = -1,-1
875 allxlim = []
876 allylim = []
877 newpanel=True
878 panelcount,stackcount = 0,0
879 while r < nr:
880 a = d[self._panelling](r)
881 b = d[self._stacking](r)
882 if a > a0 and panelcount < n:
883 if n > 1:
884 self._plotter.subplot(panelcount)
885 self._plotter.palette(0)
886 #title
887 xlab = self._abcissa and self._abcissa[panelcount] \
888 or scan._getabcissalabel()
889 if self._offset and not self._abcissa:
890 xlab += " (relative)"
891 ylab = self._ordinate and self._ordinate[panelcount] \
892 or scan._get_ordinate_label()
893 self._plotter.set_axes('xlabel', xlab)
894 self._plotter.set_axes('ylabel', ylab)
895 lbl = self._get_label(scan, r, self._panelling, self._title)
896 #if self._panelling == 'r': lbl = ''
897 if isinstance(lbl, list) or isinstance(lbl, tuple):
898 if 0 <= panelcount < len(lbl):
899 lbl = lbl[panelcount]
900 else:
901 # get default label
902 lbl = self._get_label(scan, r, self._panelling, None)
903 self._plotter.set_axes('title',lbl)
904 newpanel = True
905 stackcount = 0
906 panelcount += 1
907 if (b > b0 or newpanel) and stackcount < nstack:
908 y = []
909 if len(polmodes):
910 y = scan._getspectrum(r, polmodes[scan.getpol(r)])
911 else:
912 y = scan._getspectrum(r)
913 m = scan._getmask(r)
914 from numpy import logical_not, logical_and
915 if self._maskselection and len(self._usermask) == len(m):
916 if d[self._stacking](r) in self._maskselection[self._stacking]:
917 m = logical_and(m, self._usermask)
918 from numpy import ma, array
919 x = array(scan._getabcissa(r))
920 if self._offset:
921 x += self._offset
922 y = ma.masked_array(y,mask=logical_not(array(m,copy=False)))
923 if self._minmaxx is not None:
924 s,e = self._slice_indeces(x)
925 x = x[s:e]
926 y = y[s:e]
927 if len(x) > 1024 and rcParams['plotter.decimate']:
928 fac = len(x)/1024
929 x = x[::fac]
930 y = y[::fac]
931 llbl = self._get_label(scan, r, self._stacking, self._lmap)
932 if isinstance(llbl, list) or isinstance(llbl, tuple):
933 if 0 <= stackcount < len(llbl):
934 # use user label
935 llbl = llbl[stackcount]
936 else:
937 # get default label
938 llbl = self._get_label(scan, r, self._stacking, None)
939 self._plotter.set_line(label=llbl)
940 plotit = self._plotter.plot
941 if self._hist: plotit = self._plotter.hist
942 if len(x) > 0:
943 plotit(x,y)
944 xlim= self._minmaxx or [min(x),max(x)]
945 allxlim += xlim
946 ylim= self._minmaxy or [ma.minimum(y),ma.maximum(y)]
947 allylim += ylim
948 else:
949 xlim = self._minmaxx or []
950 allxlim += xlim
951 ylim= self._minmaxy or []
952 allylim += ylim
953 stackcount += 1
954 # last in colour stack -> autoscale x
955 if stackcount == nstack and len(allxlim) > 0:
956 allxlim.sort()
957 self._plotter.subplots[panelcount-1]['axes'].set_xlim([allxlim[0],allxlim[-1]])
958 # clear
959 allxlim =[]
960
961 newpanel = False
962 a0=a
963 b0=b
964 # ignore following rows
965 if (panelcount == n) and (stackcount == nstack):
966 # last panel -> autoscale y if ganged
967 if rcParams['plotter.ganged'] and len(allylim) > 0:
968 allylim.sort()
969 self._plotter.set_limits(ylim=[allylim[0],allylim[-1]])
970 break
971 r+=1 # next row
972 ###-S
973 self._rowcount = r+1
974 self._panelcnt += panelcount
975 if self._plotter.figmgr.casabar:
976 if self._panelcnt >= nptot-1:
977 self._plotter.figmgr.casabar.disable_next()
978 else:
979 self._plotter.figmgr.casabar.enable_next()
980 #if self._panelcnt - panelcount > 0:
981 # self._plotter.figmgr.casabar.enable_prev()
982 #else:
983 # self._plotter.figmgr.casabar.disable_prev()
984 ###-E
985 #reset the selector to the scantable's original
986 scan.set_selection(savesel)
987
988 #temporary switch-off for older matplotlib
989 #if self._fp is not None:
990 if self._fp is not None and getattr(self._plotter.figure,'findobj',False):
991 for o in self._plotter.figure.findobj(Text):
992 o.set_fontproperties(self._fp)
993
994 def _get_sortstring(self, lorders):
995 d0 = {'s': 'SCANNO', 'b': 'BEAMNO', 'i':'IFNO',
996 'p': 'POLNO', 'c': 'CYCLENO', 't' : 'TIME', 'r':None, '_r':None }
997 if not (type(lorders) == list) or not (type(lorders) == tuple):
998 return None
999 if len(lorders) > 0:
1000 lsorts = []
1001 for order in lorders:
1002 ssort = d0[order]
1003 if ssort:
1004 lsorts.append(ssort)
1005 return lsorts
1006 return None
1007
1008 def set_selection(self, selection=None, refresh=True, **kw):
1009 """
1010 Parameters:
1011 selection: a selector object (default unset the selection)
1012 refresh: True (default) or False. If True, the plot is
1013 replotted based on the new parameter setting(s).
1014 Otherwise,the parameter(s) are set without replotting.
1015 """
1016 if selection is None:
1017 # reset
1018 if len(kw) == 0:
1019 self._selection = selector()
1020 else:
1021 # try keywords
1022 for k in kw:
1023 if k not in selector.fields:
1024 raise KeyError("Invalid selection key '%s', valid keys are %s" % (k, selector.fields))
1025 self._selection = selector(**kw)
1026 elif isinstance(selection, selector):
1027 self._selection = selection
1028 else:
1029 raise TypeError("'selection' is not of type selector")
1030
1031 order = self._get_sortstring([self._panelling,self._stacking])
1032 if order:
1033 self._selection.set_order(order)
1034 if refresh and self._data: self.plot(self._data)
1035
1036 def _get_selected_n(self, scan):
1037 d1 = {'b': scan.getbeamnos, 's': scan.getscannos,
1038 'i': scan.getifnos, 'p': scan.getpolnos, 't': scan.ncycle,
1039 'r': scan.nrow, '_r': False}
1040 d2 = { 'b': self._selection.get_beams(),
1041 's': self._selection.get_scans(),
1042 'i': self._selection.get_ifs(),
1043 'p': self._selection.get_pols(),
1044 't': self._selection.get_cycles(),
1045 'r': False, '_r': 1}
1046 n = d2[self._panelling] or d1[self._panelling]()
1047 nstack = d2[self._stacking] or d1[self._stacking]()
1048 return n,nstack
1049
1050 def _get_label(self, scan, row, mode, userlabel=None):
1051 if isinstance(userlabel, list) and len(userlabel) == 0:
1052 userlabel = " "
1053 pms = dict(zip(self._selection.get_pols(),self._selection.get_poltypes()))
1054 if len(pms):
1055 poleval = scan._getpollabel(scan.getpol(row),pms[scan.getpol(row)])
1056 else:
1057 poleval = scan._getpollabel(scan.getpol(row),scan.poltype())
1058 d = {'b': "Beam "+str(scan.getbeam(row)),
1059 #'s': scan._getsourcename(row),
1060 's': "Scan "+str(scan.getscan(row))+\
1061 " ("+str(scan._getsourcename(row))+")",
1062 'i': "IF"+str(scan.getif(row)),
1063 'p': poleval,
1064 't': str(scan.get_time(row)),
1065 'r': "row "+str(row),
1066 #'_r': str(scan.get_time(row))+",\nIF"+str(scan.getif(row))+", "+poleval+", Beam"+str(scan.getbeam(row)) }
1067 '_r': "" }
1068 return userlabel or d[mode]
1069
1070 def plotazel(self, scan=None, outfile=None):
1071 #def plotazel(self):
1072 """
1073 plot azimuth and elevation versus time of a scantable
1074 """
1075 from matplotlib import pylab as PL
1076 from matplotlib.dates import DateFormatter, timezone
1077 from matplotlib.dates import HourLocator, MinuteLocator,SecondLocator, DayLocator
1078 from matplotlib.ticker import MultipleLocator
1079 from numpy import array, pi
1080 self._data = scan
1081 self._outfile = outfile
1082 dates = self._data.get_time(asdatetime=True)
1083 t = PL.date2num(dates)
1084 tz = timezone('UTC')
1085 PL.cla()
1086 PL.ioff()
1087 PL.clf()
1088 # Adjust subplot layouts
1089 if len(self._panellayout) !=6: self.set_panellayout(refresh=False)
1090 lef, bot, rig, top, wsp, hsp = self._panellayout
1091 PL.gcf().subplots_adjust(left=lef,bottom=bot,right=rig,top=top,
1092 wspace=wsp,hspace=hsp)
1093
1094 tdel = max(t) - min(t)
1095 ax = PL.subplot(2,1,1)
1096 el = array(self._data.get_elevation())*180./pi
1097 PL.ylabel('El [deg.]')
1098 dstr = dates[0].strftime('%Y/%m/%d')
1099 if tdel > 1.0:
1100 dstr2 = dates[len(dates)-1].strftime('%Y/%m/%d')
1101 dstr = dstr + " - " + dstr2
1102 majloc = DayLocator()
1103 minloc = HourLocator(range(0,23,12))
1104 timefmt = DateFormatter("%b%d")
1105 elif tdel > 24./60.:
1106 timefmt = DateFormatter('%H:%M')
1107 majloc = HourLocator()
1108 minloc = MinuteLocator(30)
1109 else:
1110 timefmt = DateFormatter('%H:%M')
1111 majloc = MinuteLocator(interval=5)
1112 minloc = SecondLocator(30)
1113
1114 PL.title(dstr)
1115 if tdel == 0.0:
1116 th = (t - PL.floor(t))*24.0
1117 PL.plot(th,el,'o',markersize=2, markerfacecolor='b', markeredgecolor='b')
1118 else:
1119 PL.plot_date(t,el,'o', markersize=2, markerfacecolor='b', markeredgecolor='b',tz=tz)
1120 #ax.grid(True)
1121 ax.xaxis.set_major_formatter(timefmt)
1122 ax.xaxis.set_major_locator(majloc)
1123 ax.xaxis.set_minor_locator(minloc)
1124 ax.yaxis.grid(True)
1125 yloc = MultipleLocator(30)
1126 ax.set_ylim(0,90)
1127 ax.yaxis.set_major_locator(yloc)
1128 if tdel > 1.0:
1129 labels = ax.get_xticklabels()
1130 # PL.setp(labels, fontsize=10, rotation=45)
1131 PL.setp(labels, fontsize=10)
1132
1133 # Az plot
1134 az = array(self._data.get_azimuth())*180./pi
1135 if min(az) < 0:
1136 for irow in range(len(az)):
1137 if az[irow] < 0: az[irow] += 360.0
1138
1139 ax2 = PL.subplot(2,1,2)
1140 #PL.xlabel('Time (UT [hour])')
1141 PL.ylabel('Az [deg.]')
1142 if tdel == 0.0:
1143 PL.plot(th,az,'o',markersize=2, markeredgecolor='b',markerfacecolor='b')
1144 else:
1145 PL.plot_date(t,az,'o', markersize=2,markeredgecolor='b',markerfacecolor='b',tz=tz)
1146 ax2.xaxis.set_major_formatter(timefmt)
1147 ax2.xaxis.set_major_locator(majloc)
1148 ax2.xaxis.set_minor_locator(minloc)
1149 #ax2.grid(True)
1150 ax2.set_ylim(0,360)
1151 ax2.yaxis.grid(True)
1152 #hfmt = DateFormatter('%H')
1153 #hloc = HourLocator()
1154 yloc = MultipleLocator(60)
1155 ax2.yaxis.set_major_locator(yloc)
1156 if tdel > 1.0:
1157 labels = ax2.get_xticklabels()
1158 PL.setp(labels, fontsize=10)
1159 PL.xlabel('Time (UT [day])')
1160 else:
1161 PL.xlabel('Time (UT [hour])')
1162
1163 PL.ion()
1164 PL.draw()
1165 if (self._outfile is not None):
1166 PL.savefig(self._outfile)
1167
1168 def plotpointing(self, scan=None, outfile=None):
1169 #def plotpointing(self):
1170 """
1171 plot telescope pointings
1172 """
1173 from matplotlib import pylab as PL
1174 from numpy import array, pi
1175 self._data = scan
1176 self._outfile = outfile
1177 dir = array(self._data.get_directionval()).transpose()
1178 ra = dir[0]*180./pi
1179 dec = dir[1]*180./pi
1180 PL.cla()
1181 #PL.ioff()
1182 PL.clf()
1183 # Adjust subplot layouts
1184 if len(self._panellayout) !=6: self.set_panellayout(refresh=False)
1185 lef, bot, rig, top, wsp, hsp = self._panellayout
1186 PL.gcf().subplots_adjust(left=lef,bottom=bot,right=rig,top=top,
1187 wspace=wsp,hspace=hsp)
1188 ax = PL.gca()
1189 #ax = PL.axes([0.1,0.1,0.8,0.8])
1190 #ax = PL.axes([0.1,0.1,0.8,0.8])
1191 ax.set_aspect('equal')
1192 PL.plot(ra, dec, 'b,')
1193 PL.xlabel('RA [deg.]')
1194 PL.ylabel('Declination [deg.]')
1195 PL.title('Telescope pointings')
1196 [xmin,xmax,ymin,ymax] = PL.axis()
1197 PL.axis([xmax,xmin,ymin,ymax])
1198 #PL.ion()
1199 PL.draw()
1200 if (self._outfile is not None):
1201 PL.savefig(self._outfile)
1202
1203 # plot total power data
1204 # plotting in time is not yet implemented..
1205 @asaplog_post_dec
1206 def plottp(self, scan=None, outfile=None):
1207 if self._plotter.is_dead:
1208 if hasattr(self._plotter.figmgr,'casabar'):
1209 del self._plotter.figmgr.casabar
1210 self._plotter = self._newplotter()
1211 self._plotter.figmgr.casabar=self._newcasabar()
1212 self._plotter.hold()
1213 self._plotter.clear()
1214 from asap import scantable
1215 if not self._data and not scan:
1216 msg = "Input is not a scantable"
1217 raise TypeError(msg)
1218 if isinstance(scan, scantable):
1219 if self._data is not None:
1220 if scan != self._data:
1221 self._data = scan
1222 # reset
1223 self._reset()
1224 else:
1225 self._data = scan
1226 self._reset()
1227 # ranges become invalid when abcissa changes?
1228 #if self._abcunit and self._abcunit != self._data.get_unit():
1229 # self._minmaxx = None
1230 # self._minmaxy = None
1231 # self._abcunit = self._data.get_unit()
1232 # self._datamask = None
1233
1234 # Adjust subplot layouts
1235 if len(self._panellayout) !=6: self.set_panellayout(refresh=False)
1236 lef, bot, rig, top, wsp, hsp = self._panellayout
1237 self._plotter.figure.subplots_adjust(
1238 left=lef,bottom=bot,right=rig,top=top,wspace=wsp,hspace=hsp)
1239 if self._plotter.figmgr.casabar: self._plotter.figmgr.casabar.disable_button()
1240 self._plottp(self._data)
1241 if self._minmaxy is not None:
1242 self._plotter.set_limits(ylim=self._minmaxy)
1243 self._plotter.release()
1244 self._plotter.tidy()
1245 self._plotter.show(hardrefresh=False)
1246 return
1247
1248 def _plottp(self,scan):
1249 """
1250 private method for plotting total power data
1251 """
1252 from numpy import ma, array, arange, logical_not
1253 r=0
1254 nr = scan.nrow()
1255 a0,b0 = -1,-1
1256 allxlim = []
1257 allylim = []
1258 y=[]
1259 self._plotter.set_panels()
1260 self._plotter.palette(0)
1261 #title
1262 #xlab = self._abcissa and self._abcissa[panelcount] \
1263 # or scan._getabcissalabel()
1264 #ylab = self._ordinate and self._ordinate[panelcount] \
1265 # or scan._get_ordinate_label()
1266 xlab = self._abcissa or 'row number' #or Time
1267 ylab = self._ordinate or scan._get_ordinate_label()
1268 self._plotter.set_axes('xlabel',xlab)
1269 self._plotter.set_axes('ylabel',ylab)
1270 lbl = self._get_label(scan, r, 's', self._title)
1271 if isinstance(lbl, list) or isinstance(lbl, tuple):
1272 # if 0 <= panelcount < len(lbl):
1273 # lbl = lbl[panelcount]
1274 # else:
1275 # get default label
1276 lbl = self._get_label(scan, r, self._panelling, None)
1277 self._plotter.set_axes('title',lbl)
1278 y=array(scan._get_column(scan._getspectrum,-1))
1279 m = array(scan._get_column(scan._getmask,-1))
1280 y = ma.masked_array(y,mask=logical_not(array(m,copy=False)))
1281 x = arange(len(y))
1282 # try to handle spectral data somewhat...
1283 l,m = y.shape
1284 if m > 1:
1285 y=y.mean(axis=1)
1286 plotit = self._plotter.plot
1287 llbl = self._get_label(scan, r, self._stacking, None)
1288 self._plotter.set_line(label=llbl)
1289 if len(x) > 0:
1290 plotit(x,y)
1291
1292
1293 # forwards to matplotlib.Figure.text
1294 def figtext(self, *args, **kwargs):
1295 """
1296 Add text to figure at location x,y (relative 0-1 coords).
1297 This method forwards *args and **kwargs to a Matplotlib method,
1298 matplotlib.Figure.text.
1299 See the method help for detailed information.
1300 """
1301 self._plotter.text(*args, **kwargs)
1302 # end matplotlib.Figure.text forwarding function
1303
1304
1305 # printing header information
1306 @asaplog_post_dec
1307 def print_header(self, plot=True, fontsize=9, logger=False, selstr='', extrastr=''):
1308 """
1309 print data (scantable) header on the plot and/or logger.
1310 Parameters:
1311 plot: whether or not print header info on the plot.
1312 fontsize: header font size (valid only plot=True)
1313 autoscale: whether or not autoscale the plot (valid only plot=True)
1314 logger: whether or not print header info on the logger.
1315 selstr: additional selection string (not verified)
1316 extrastr: additional string to print (not verified)
1317 """
1318 if not plot and not logger:
1319 return
1320 if not self._data:
1321 raise RuntimeError("No scantable has been set yet.")
1322 # Now header will be printed on plot and/or logger.
1323 # Get header information and format it.
1324 ssum=self._data.__str__()
1325 # Print Observation header to the upper-left corner of plot
1326 if plot:
1327 headstr=[ssum[ssum.find('Observer:'):ssum.find('Flux Unit:')]]
1328 headstr.append(ssum[ssum.find('Beams:'):ssum.find('Observer:')]
1329 +ssum[ssum.find('Rest Freqs:'):ssum.find('Abcissa:')])
1330 if extrastr != '': headstr[0]=extrastr+'\n'+headstr[0]
1331 #headstr[1]='Data File: '+(filestr or 'unknown')+'\n'+headstr[1]
1332 ssel='***Selections***\n'+(selstr+self._data.get_selection().__str__() or 'none')
1333 headstr.append(ssel)
1334 nstcol=len(headstr)
1335
1336 self._plotter.hold()
1337 for i in range(nstcol):
1338 self._plotter.figure.text(0.03+float(i)/nstcol,0.98,
1339 headstr[i],
1340 horizontalalignment='left',
1341 verticalalignment='top',
1342 fontsize=fontsize)
1343 import time
1344 self._plotter.figure.text(0.99,0.0,
1345 time.strftime("%a %d %b %Y %H:%M:%S %Z"),
1346 horizontalalignment='right',
1347 verticalalignment='bottom',fontsize=8)
1348 self._plotter.release()
1349 del headstr, ssel
1350 if logger:
1351 asaplog.push("----------------\n Plot Summary\n----------------")
1352 asaplog.push(extrastr)
1353 asaplog.push(ssum[ssum.find('Beams:'):])
1354 del ssum
Note: See TracBrowser for help on using the repository browser.