source: branches/mergetest/python/asapplotter.py@ 1779

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

New Development: Yes

JIRA Issue: No (test merging alma branch)

Ready for Test: Yes

Interface Changes: Yes

What Interface Changed:

Test Programs:

Put in Release Notes: No

Module(s):

Description:


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