source: trunk/python/asapplotter.py@ 2698

Last change on this file since 2698 was 2698, checked in by Kana Sugimoto, 12 years ago

New Development: No

JIRA Issue: No

Ready for Test: Yes

Interface Changes: No

What Interface Changed:

Test Programs:

Put in Release Notes: No

Module(s):

Description:

perparation for refactoring. chaged order of methods in code.


  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 79.4 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
8from matplotlib import _pylab_helpers
9
10import re
11
12def new_asaplot(visible=None,**kwargs):
13 """
14 Returns a new asaplot instance based on the backend settings.
15 """
16 if visible == None:
17 visible = rcParams['plotter.gui']
18
19 backend=matplotlib.get_backend()
20 if not visible:
21 from asap.asaplot import asaplot
22 elif backend == 'TkAgg':
23 from asap.asaplotgui import asaplotgui as asaplot
24 elif backend == 'Qt4Agg':
25 from asap.asaplotgui_qt4 import asaplotgui as asaplot
26 elif backend == 'GTkAgg':
27 from asap.asaplotgui_gtk import asaplotgui as asaplot
28 else:
29 from asap.asaplot import asaplot
30 return asaplot(**kwargs)
31
32class asapplotter:
33 """
34 The ASAP plotter.
35 By default the plotter is set up to plot polarisations
36 'colour stacked' and scantables across panels.
37
38 .. note::
39
40 Currenly it only plots 'spectra' not Tsys or
41 other variables.
42
43 """
44 def __init__(self, visible=None , **kwargs):
45 self._visible = rcParams['plotter.gui']
46 if visible is not None:
47 self._visible = visible
48 self._plotter = None
49 self._inikwg = kwargs
50
51 # plot settings
52 self._colormap = None
53 self._linestyles = None
54 self._fp = FontProperties()
55 self._rows = None
56 self._cols = None
57 self._minmaxx = None
58 self._minmaxy = None
59 self._margins = self.set_margin(refresh=False)
60 self._legendloc = None
61 # scantable plot settings
62 self._panelling = None
63 self._stacking = None
64 self.set_panelling()
65 self.set_stacking()
66 self._hist = rcParams['plotter.histogram']
67 # scantable dependent settings
68 self._data = None
69 self._abcunit = None
70 self._headtext = {'string': None, 'textobj': None}
71 self._selection = selector()
72 self._usermask = []
73 self._maskselection = None
74 self._offset = None
75 self._lmap = None
76 self._title = None
77 self._ordinate = None
78 self._abcissa = None
79 # cursors for page iteration
80 self._startrow = 0
81 self._ipanel = -1
82 self._panelrows = []
83
84 def _translate(self, instr):
85 keys = "s b i p t r".split()
86 if isinstance(instr, str):
87 for key in keys:
88 if instr.lower().startswith(key):
89 return key
90 return None
91
92 @asaplog_post_dec
93 def _reload_plotter(self):
94 if self._plotter is not None:
95 #if not self._plotter.is_dead:
96 # # clear lines and axes
97 # try:
98 # self._plotter.clear()
99 # except: # Can't remove when already killed.
100 # pass
101 if self.casabar_exists():
102 del self._plotter.figmgr.casabar
103 self._plotter.quit()
104 del self._plotter
105 asaplog.push('Loading new plotter')
106 self._plotter = new_asaplot(self._visible,**self._inikwg)
107 self._plotter.figmgr.casabar=self._new_custombar()
108 # just to make sure they're set
109 self._plotter.palette(color=0,colormap=self._colormap,
110 linestyle=0,linestyles=self._linestyles)
111 self._plotter.legend(self._legendloc)
112
113 def _new_custombar(self):
114 backend=matplotlib.get_backend()
115 if not self._visible:
116 return None
117 elif backend == "TkAgg":
118 from asap.customgui_tkagg import CustomToolbarTkAgg
119 return CustomToolbarTkAgg(self)
120 elif backend == "Qt4Agg":
121 from asap.customgui_qt4agg import CustomToolbarQT4Agg
122 return CustomToolbarQT4Agg(self)
123 return None
124
125 def casabar_exists(self):
126 if not hasattr(self._plotter.figmgr,'casabar'):
127 return False
128 elif self._plotter.figmgr.casabar:
129 return True
130 return False
131
132 def _assert_plotter(self,action="status",errmsg=None):
133 """
134 Check plot window status. Returns True if plot window is alive.
135 Parameters
136 action: An action to take if the plotter window is not alive.
137 ['status'|'reload'|'halt']
138 The action 'status' simply returns False if asaplot
139 is not alive. When action='reload', plot window is
140 reloaded and the method returns True. Finally, an
141 error is raised when action='halt'.
142 errmsg: An error (warning) message to send to the logger,
143 when plot window is not alive.
144 """
145 isAlive = (self._plotter is not None) and self._plotter._alive()
146 # More tests
147 #if isAlive:
148 # if self._plotter.figmgr:
149 # figmgr = self._plotter.figmgr
150 # figid = figmgr.num
151 # # Make sure figid=0 is what asapplotter expects.
152 # # It might be already destroied/overridden by matplotlib
153 # # commands or other plotting methods using asaplot.
154 # isAlive = _pylab_helpers.Gcf.has_fignum(figid) and \
155 # (figmgr == \
156 # _pylab_helpers.Gcf.get_fig_manager(figid))
157 # else:
158 # isAlive = False
159
160 if isAlive:
161 return True
162 # Plotter is not alive.
163 haltmsg = "Plotter window has not yet been loaded or is closed."
164 if type(errmsg)==str and len(errmsg) > 0:
165 haltmsg = errmsg
166
167 if action.upper().startswith("R"):
168 # reload plotter
169 self._reload_plotter()
170 return True
171 elif action.upper().startswith("H"):
172 # halt
173 asaplog.push(haltmsg)
174 asaplog.post("ERROR")
175 raise RuntimeError(haltmsg)
176 else:
177 if errmsg:
178 asaplog.push(errmsg)
179 asaplog.post("WARN")
180 return False
181
182
183 def gca(self):
184 errmsg = "No axis to retun. Need to plot first."
185 if not self._assert_plotter(action="status",errmsg=errmsg):
186 return None
187 return self._plotter.figure.gca()
188
189 def refresh(self):
190 """Do a soft refresh"""
191 errmsg = "No figure to re-plot. Need to plot first."
192 self._assert_plotter(action="halt",errmsg=errmsg)
193
194 self._plotter.figure.show()
195
196 def save(self, filename=None, orientation=None, dpi=None):
197 """
198 Save the plot to a file. The known formats are 'png', 'ps', 'eps'.
199 Parameters:
200 filename: The name of the output file. This is optional
201 and autodetects the image format from the file
202 suffix. If non filename is specified a file
203 called 'yyyymmdd_hhmmss.png' is created in the
204 current directory.
205 orientation: optional parameter for postscript only (not eps).
206 'landscape', 'portrait' or None (default) are valid.
207 If None is choosen for 'ps' output, the plot is
208 automatically oriented to fill the page.
209 dpi: The dpi of the output non-ps plot
210 """
211 errmsg = "Cannot save figure. Need to plot first."
212 self._assert_plotter(action="halt",errmsg=errmsg)
213
214 self._plotter.save(filename,orientation,dpi)
215 return
216
217 def create_mask(self, nwin=1, panel=0, color=None):
218 """
219 Interactively define a mask. It retruns a mask that is equivalent to
220 the one created manually with scantable.create_mask.
221 Parameters:
222 nwin: The number of mask windows to create interactively
223 default is 1.
224 panel: Which panel to use for mask selection. This is useful
225 if different IFs are spread over panels (default 0)
226 """
227 ## this method relies on already plotted figure
228 if not self._assert_plotter(action="status") or (self._data is None):
229 msg = "Cannot create mask interactively on plot. Can only create mask after plotting."
230 asaplog.push( msg )
231 asaplog.post( "ERROR" )
232 return []
233 outmask = []
234 self._plotter.subplot(panel)
235 xmin, xmax = self._plotter.axes.get_xlim()
236 marg = 0.05*(xmax-xmin)
237 self._plotter.axes.set_xlim(xmin-marg, xmax+marg)
238 self.refresh()
239
240 def cleanup(lines=False, texts=False, refresh=False):
241 if lines:
242 del self._plotter.axes.lines[-1]
243 if texts:
244 del self._plotter.axes.texts[-1]
245 if refresh:
246 self.refresh()
247
248 for w in xrange(nwin):
249 wpos = []
250 self.text(0.05,1.0, "Add start boundary",
251 coords="relative", fontsize=10)
252 point = self._plotter.get_point()
253 cleanup(texts=True)
254 if point is None:
255 continue
256 wpos.append(point[0])
257 self.axvline(wpos[0], color=color)
258 self.text(0.05,1.0, "Add end boundary", coords="relative", fontsize=10)
259 point = self._plotter.get_point()
260 cleanup(texts=True, lines=True)
261 if point is None:
262 self.refresh()
263 continue
264 wpos.append(point[0])
265 self.axvspan(wpos[0], wpos[1], alpha=0.1,
266 edgecolor=color, facecolor=color)
267 ymin, ymax = self._plotter.axes.get_ylim()
268 outmask.append(wpos)
269
270 self._plotter.axes.set_xlim(xmin, xmax)
271 self.refresh()
272 if len(outmask) > 0:
273 return self._data.create_mask(*outmask)
274 return []
275
276 # forwards to matplotlib axes
277 def text(self, *args, **kwargs):
278 self._assert_plotter(action="reload")
279 if kwargs.has_key("interactive"):
280 if kwargs.pop("interactive"):
281 pos = self._plotter.get_point()
282 args = tuple(pos)+args
283 self._axes_callback("text", *args, **kwargs)
284
285 text.__doc__ = matplotlib.axes.Axes.text.__doc__
286
287 def arrow(self, *args, **kwargs):
288 self._assert_plotter(action="reload")
289 if kwargs.has_key("interactive"):
290 if kwargs.pop("interactive"):
291 pos = self._plotter.get_region()
292 dpos = (pos[0][0], pos[0][1],
293 pos[1][0]-pos[0][0],
294 pos[1][1] - pos[0][1])
295 args = dpos + args
296 self._axes_callback("arrow", *args, **kwargs)
297
298 arrow.__doc__ = matplotlib.axes.Axes.arrow.__doc__
299
300 def annotate(self, text, xy=None, xytext=None, **kwargs):
301 self._assert_plotter(action="reload")
302 if kwargs.has_key("interactive"):
303 if kwargs.pop("interactive"):
304 xy = self._plotter.get_point()
305 xytext = self._plotter.get_point()
306 if not kwargs.has_key("arrowprops"):
307 kwargs["arrowprops"] = dict(arrowstyle="->")
308 self._axes_callback("annotate", text, xy, xytext, **kwargs)
309
310 annotate.__doc__ = matplotlib.axes.Axes.annotate.__doc__
311
312 def axvline(self, *args, **kwargs):
313 self._assert_plotter(action="reload")
314 if kwargs.has_key("interactive"):
315 if kwargs.pop("interactive"):
316 pos = self._plotter.get_point()
317 args = (pos[0],)+args
318 self._axes_callback("axvline", *args, **kwargs)
319
320 axvline.__doc__ = matplotlib.axes.Axes.axvline.__doc__
321
322 def axhline(self, *args, **kwargs):
323 self._assert_plotter(action="reload")
324 if kwargs.has_key("interactive"):
325 if kwargs.pop("interactive"):
326 pos = self._plotter.get_point()
327 args = (pos[1],)+args
328 self._axes_callback("axhline", *args, **kwargs)
329
330 axhline.__doc__ = matplotlib.axes.Axes.axhline.__doc__
331
332 def axvspan(self, *args, **kwargs):
333 self._assert_plotter(action="reload")
334 if kwargs.has_key("interactive"):
335 if kwargs.pop("interactive"):
336 pos = self._plotter.get_region()
337 dpos = (pos[0][0], pos[1][0])
338 args = dpos + args
339 self._axes_callback("axvspan", *args, **kwargs)
340 # hack to preventy mpl from redrawing the patch
341 # it seem to convert the patch into lines on every draw.
342 # This doesn't happen in a test script???
343 #del self._plotter.axes.patches[-1]
344
345 axvspan.__doc__ = matplotlib.axes.Axes.axvspan.__doc__
346
347 def axhspan(self, *args, **kwargs):
348 self._assert_plotter(action="reload")
349 if kwargs.has_key("interactive"):
350 if kwargs.pop("interactive"):
351 pos = self._plotter.get_region()
352 dpos = (pos[0][1], pos[1][1])
353 args = dpos + args
354 self._axes_callback("axhspan", *args, **kwargs)
355 # hack to preventy mpl from redrawing the patch
356 # it seem to convert the patch into lines on every draw.
357 # This doesn't happen in a test script???
358 #del self._plotter.axes.patches[-1]
359
360 axhspan.__doc__ = matplotlib.axes.Axes.axhspan.__doc__
361
362 def _axes_callback(self, axesfunc, *args, **kwargs):
363 self._assert_plotter(action="reload")
364 panel = 0
365 if kwargs.has_key("panel"):
366 panel = kwargs.pop("panel")
367 coords = None
368 if kwargs.has_key("coords"):
369 coords = kwargs.pop("coords")
370 if coords.lower() == 'world':
371 kwargs["transform"] = self._plotter.axes.transData
372 elif coords.lower() == 'relative':
373 kwargs["transform"] = self._plotter.axes.transAxes
374 self._plotter.subplot(panel)
375 self._plotter.axes.set_autoscale_on(False)
376 getattr(self._plotter.axes, axesfunc)(*args, **kwargs)
377 self._plotter.show(False)
378 self._plotter.axes.set_autoscale_on(True)
379 # end matplotlib.axes fowarding functions
380
381 # forwards to matplotlib.Figure.text
382 def figtext(self, *args, **kwargs):
383 """
384 Add text to figure at location x,y (relative 0-1 coords).
385 This method forwards *args and **kwargs to a Matplotlib method,
386 matplotlib.Figure.text.
387 See the method help for detailed information.
388 """
389 self._assert_plotter(action="reload")
390 self._plotter.text(*args, **kwargs)
391 # end matplotlib.Figure.text forwarding function
392
393 # plot setttings
394 @asaplog_post_dec
395 def set_data(self, scan, refresh=True):
396 """
397 Set a scantable to plot.
398 Parameters:
399 scan: a scantable
400 refresh: True (default) or False. If True, the plot is
401 replotted based on the new parameter setting(s).
402 Otherwise,the parameter(s) are set without replotting.
403 Note:
404 The user specified masks and data selections will be reset
405 if a new scantable is set. This method should be called before
406 setting data selections (set_selection) and/or masks (set_mask).
407 """
408 from asap import scantable
409 if isinstance(scan, scantable):
410 if (self._data is not None) and (scan != self._data):
411 del self._data
412 msg = "A new scantable is set to the plotter. "\
413 "The masks and data selections are reset."
414 asaplog.push( msg )
415 self._data = scan
416 # reset
417 self._reset()
418 else:
419 msg = "Input is not a scantable"
420 raise TypeError(msg)
421
422 # ranges become invalid when unit changes
423 if self._abcunit and self._abcunit != self._data.get_unit():
424 self._minmaxx = None
425 self._minmaxy = None
426 self._abcunit = self._data.get_unit()
427 if refresh: self.plot()
428
429 @asaplog_post_dec
430 def set_mode(self, stacking=None, panelling=None, refresh=True):
431 """
432 Set the plots look and feel, i.e. what you want to see on the plot.
433 Parameters:
434 stacking: tell the plotter which variable to plot
435 as line colour overlays (default 'pol')
436 panelling: tell the plotter which variable to plot
437 across multiple panels (default 'scan'
438 refresh: True (default) or False. If True, the plot is
439 replotted based on the new parameter setting(s).
440 Otherwise,the parameter(s) are set without replotting.
441 Note:
442 Valid modes are:
443 'beam' 'Beam' 'b': Beams
444 'if' 'IF' 'i': IFs
445 'pol' 'Pol' 'p': Polarisations
446 'scan' 'Scan' 's': Scans
447 'time' 'Time' 't': Times
448 'row' 'Row' 'r': Rows
449 When either 'stacking' or 'panelling' is set to 'row',
450 the other parameter setting is ignored.
451 """
452 msg = "Invalid mode"
453 if not self.set_panelling(panelling) or \
454 not self.set_stacking(stacking):
455 raise TypeError(msg)
456 #if self._panelling == 'r':
457 # self._stacking = '_r'
458 #if self._stacking == 'r':
459 # self._panelling = '_r'
460 if refresh and self._data: self.plot(self._data)
461 return
462
463 def set_stacking(self, what=None):
464 """Set the 'stacking' mode i.e. which type of spectra should be
465 overlayed.
466 """
467 mode = what
468 if mode is None:
469 mode = rcParams['plotter.stacking']
470 md = self._translate(mode)
471 if md:
472 self._stacking = md
473 self._lmap = None
474 # new mode is set. need to reset counters for multi page plotting
475 self._reset_counters()
476 return True
477 return False
478
479 def set_panelling(self, what=None):
480 """Set the 'panelling' mode i.e. which type of spectra should be
481 spread across different panels.
482 """
483
484 mode = what
485 if mode is None:
486 mode = rcParams['plotter.panelling']
487 md = self._translate(mode)
488 if md:
489 self._panelling = md
490 self._title = None
491 # new mode is set. need to reset counters for multi page plotting
492 self._reset_counters()
493 return True
494 return False
495
496 def set_layout(self,rows=None,cols=None,refresh=True):
497 """
498 Set the multi-panel layout, i.e. how many rows and columns plots
499 are visible.
500 Parameters:
501 rows: The number of rows of plots
502 cols: The number of columns of plots
503 refresh: True (default) or False. If True, the plot is
504 replotted based on the new parameter setting(s).
505 Otherwise,the parameter(s) are set without replotting.
506 Note:
507 If no argument is given, the potter reverts to its auto-plot
508 behaviour.
509 """
510 self._rows = rows
511 self._cols = cols
512 if refresh and self._data: self.plot(self._data)
513 return
514
515 def set_range(self,xstart=None,xend=None,ystart=None,yend=None,refresh=True, offset=None):
516 """
517 Set the range of interest on the abcissa of the plot
518 Parameters:
519 [x,y]start,[x,y]end: The start and end points of the 'zoom' window
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 offset: shift the abcissa by the given amount. The abcissa label will
524 have '(relative)' appended to it.
525 Note:
526 These become non-sensical when the unit changes.
527 use plotter.set_range() without parameters to reset
528
529 """
530 self._offset = offset
531 if xstart is None and xend is None:
532 self._minmaxx = None
533 else:
534 self._minmaxx = [xstart,xend]
535 if ystart is None and yend is None:
536 self._minmaxy = None
537 else:
538 self._minmaxy = [ystart,yend]
539 if refresh and self._data: self.plot(self._data)
540 return
541
542 def set_legend(self, mp=None, fontsize = None, mode = 0, refresh=True):
543 """
544 Specify a mapping for the legend instead of using the default
545 indices:
546 Parameters:
547 mp: a list of 'strings'. This should have the same length
548 as the number of elements on the legend and then maps
549 to the indeces in order. It is possible to uses latex
550 math expression. These have to be enclosed in r'',
551 e.g. r'$x^{2}$'
552 fontsize: The font size of the label (default None)
553 mode: where to display the legend
554 Any other value for loc else disables the legend:
555 0: auto
556 1: upper right
557 2: upper left
558 3: lower left
559 4: lower right
560 5: right
561 6: center left
562 7: center right
563 8: lower center
564 9: upper center
565 10: center
566 refresh: True (default) or False. If True, the plot is
567 replotted based on the new parameter setting(s).
568 Otherwise,the parameter(s) are set without replotting.
569
570 Example:
571 If the data has two IFs/rest frequencies with index 0 and 1
572 for CO and SiO:
573 plotter.set_stacking('i')
574 plotter.set_legend(['CO','SiO'])
575 plotter.plot()
576 plotter.set_legend([r'$^{12}CO$', r'SiO'])
577 """
578 self._lmap = mp
579 #self._plotter.legend(mode)
580 self._legendloc = mode
581 if isinstance(fontsize, int):
582 from matplotlib import rc as rcp
583 rcp('legend', fontsize=fontsize)
584 if refresh and self._data: self.plot(self._data)
585 return
586
587 def set_title(self, title=None, fontsize=None, refresh=True):
588 """
589 Set the title of sub-plots. If multiple sub-plots are plotted,
590 multiple titles have to be specified.
591 Parameters:
592 title: a list of titles of sub-plots.
593 fontsize: a font size of titles (integer)
594 refresh: True (default) or False. If True, the plot is
595 replotted based on the new parameter setting(s).
596 Otherwise,the parameter(s) are set without replotting.
597 Example:
598 # two panels are visible on the plotter
599 plotter.set_title(['First Panel','Second Panel'])
600 """
601 self._title = title
602 if isinstance(fontsize, int):
603 from matplotlib import rc as rcp
604 rcp('axes', titlesize=fontsize)
605 if refresh and self._data: self.plot(self._data)
606 return
607
608 def set_ordinate(self, ordinate=None, fontsize=None, refresh=True):
609 """
610 Set the y-axis label of the plot. If multiple panels are plotted,
611 multiple labels have to be specified.
612 Parameters:
613 ordinate: a list of ordinate labels. None (default) let
614 data determine the labels
615 fontsize: a font size of vertical axis labels (integer)
616 refresh: True (default) or False. If True, the plot is
617 replotted based on the new parameter setting(s).
618 Otherwise,the parameter(s) are set without replotting.
619 Example:
620 # two panels are visible on the plotter
621 plotter.set_ordinate(['First Y-Axis','Second Y-Axis'])
622 """
623 self._ordinate = ordinate
624 if isinstance(fontsize, int):
625 from matplotlib import rc as rcp
626 rcp('axes', labelsize=fontsize)
627 rcp('ytick', labelsize=fontsize)
628 if refresh and self._data: self.plot(self._data)
629 return
630
631 def set_abcissa(self, abcissa=None, fontsize=None, refresh=True):
632 """
633 Set the x-axis label of the plot. If multiple panels are plotted,
634 multiple labels have to be specified.
635 Parameters:
636 abcissa: a list of abcissa labels. None (default) let
637 data determine the labels
638 fontsize: a font size of horizontal axis labels (integer)
639 refresh: True (default) or False. If True, the plot is
640 replotted based on the new parameter setting(s).
641 Otherwise,the parameter(s) are set without replotting.
642 Example:
643 # two panels are visible on the plotter
644 plotter.set_ordinate(['First X-Axis','Second X-Axis'])
645 """
646 self._abcissa = abcissa
647 if isinstance(fontsize, int):
648 from matplotlib import rc as rcp
649 rcp('axes', labelsize=fontsize)
650 rcp('xtick', labelsize=fontsize)
651 if refresh and self._data: self.plot(self._data)
652 return
653
654 def set_colors(self, colmap, refresh=True):
655 """
656 Set the colours to be used. The plotter will cycle through
657 these colours when lines are overlaid (stacking mode).
658 Parameters:
659 colmap: a list of colour names
660 refresh: True (default) or False. If True, the plot is
661 replotted based on the new parameter setting(s).
662 Otherwise,the parameter(s) are set without replotting.
663 Example:
664 plotter.set_colors('red green blue')
665 # If for example four lines are overlaid e.g I Q U V
666 # 'I' will be 'red', 'Q' will be 'green', U will be 'blue'
667 # and 'V' will be 'red' again.
668 """
669 #if isinstance(colmap,str):
670 # colmap = colmap.split()
671 #self._plotter.palette(0, colormap=colmap)
672 self._colormap = colmap
673 if refresh and self._data: self.plot(self._data)
674
675 # alias for english speakers
676 set_colours = set_colors
677
678 def set_histogram(self, hist=True, linewidth=None, refresh=True):
679 """
680 Enable/Disable histogram-like plotting.
681 Parameters:
682 hist: True (default) or False. The fisrt default
683 is taken from the .asaprc setting
684 plotter.histogram
685 linewidth: a line width
686 refresh: True (default) or False. If True, the plot is
687 replotted based on the new parameter setting(s).
688 Otherwise,the parameter(s) are set without replotting.
689 """
690 self._hist = hist
691 if isinstance(linewidth, float) or isinstance(linewidth, int):
692 from matplotlib import rc as rcp
693 rcp('lines', linewidth=linewidth)
694 if refresh and self._data: self.plot(self._data)
695
696 def set_linestyles(self, linestyles=None, linewidth=None, refresh=True):
697 """
698 Set the linestyles to be used. The plotter will cycle through
699 these linestyles when lines are overlaid (stacking mode) AND
700 only one color has been set.
701 Parameters:
702 linestyles: a list of linestyles to use.
703 'line', 'dashed', 'dotted', 'dashdot',
704 'dashdotdot' and 'dashdashdot' are
705 possible
706 linewidth: a line width
707 refresh: True (default) or False. If True, the plot is
708 replotted based on the new parameter setting(s).
709 Otherwise,the parameter(s) are set without replotting.
710 Example:
711 plotter.set_colors('black')
712 plotter.set_linestyles('line dashed dotted dashdot')
713 # If for example four lines are overlaid e.g I Q U V
714 # 'I' will be 'solid', 'Q' will be 'dashed',
715 # U will be 'dotted' and 'V' will be 'dashdot'.
716 """
717 #if isinstance(linestyles,str):
718 # linestyles = linestyles.split()
719 #self._plotter.palette(color=0,linestyle=0,linestyles=linestyles)
720 self._linestyles = linestyles
721 if isinstance(linewidth, float) or isinstance(linewidth, int):
722 from matplotlib import rc as rcp
723 rcp('lines', linewidth=linewidth)
724 if refresh and self._data: self.plot(self._data)
725
726 def set_font(self, refresh=True,**kwargs):
727 """
728 Set font properties.
729 Parameters:
730 family: one of 'sans-serif', 'serif', 'cursive', 'fantasy', 'monospace'
731 style: one of 'normal' (or 'roman'), 'italic' or 'oblique'
732 weight: one of 'normal or 'bold'
733 size: the 'general' font size, individual elements can be adjusted
734 seperately
735 refresh: True (default) or False. If True, the plot is
736 replotted based on the new parameter setting(s).
737 Otherwise,the parameter(s) are set without replotting.
738 """
739 from matplotlib import rc as rcp
740 fdict = {}
741 for k,v in kwargs.iteritems():
742 if v:
743 fdict[k] = v
744 self._fp = FontProperties(**fdict)
745 if refresh and self._data: self.plot(self._data)
746
747 def set_margin(self,margin=[],refresh=True):
748 """
749 Set margins between subplots and plot edges.
750 Parameters:
751 margin: a list of margins in figure coordinate (0-1),
752 i.e., fraction of the figure width or height.
753 The order of elements should be:
754 [left, bottom, right, top, horizontal space btw panels,
755 vertical space btw panels].
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 Note
760 * When margin is not specified, the values are reset to the defaults
761 of matplotlib.
762 * If any element is set to be None, the current value is adopted.
763 """
764 if margin == []: self._margins=self._reset_margin()
765 else:
766 self._margins=[None]*6
767 self._margins[0:len(margin)]=margin
768 #print "panel margin set to ",self._margins
769 if refresh and self._data: self.plot(self._data)
770
771 def _reset_margin(self):
772 ks=map(lambda x: 'figure.subplot.'+x,
773 ['left','bottom','right','top','hspace','wspace'])
774 return map(matplotlib.rcParams.get,ks)
775
776 def plot_lines(self, linecat=None, doppler=0.0, deltachan=10, rotate=90.0,
777 location=None):
778 """
779 Plot a line catalog.
780 Parameters:
781 linecat: the linecatalog to plot
782 doppler: the velocity shift to apply to the frequencies
783 deltachan: the number of channels to include each side of the
784 line to determine a local maximum/minimum
785 rotate: the rotation (in degrees) for the text label (default 90.0)
786 location: the location of the line annotation from the 'top',
787 'bottom' or alternate (None - the default)
788 Notes:
789 If the spectrum is flagged no line will be drawn in that location.
790 """
791 errmsg = "Cannot plot spectral lines. Need to plot scantable first."
792 self._assert_plotter(action="halt",errmsg=errmsg)
793 if not self._data:
794 raise RuntimeError("No scantable has been plotted yet.")
795 from asap._asap import linecatalog
796 if not isinstance(linecat, linecatalog):
797 raise ValueError("'linecat' isn't of type linecatalog.")
798 if not self._data.get_unit().endswith("Hz"):
799 raise RuntimeError("Can only overlay linecatalogs when data is in frequency.")
800 from numpy import ma
801 for j in range(len(self._plotter.subplots)):
802 self._plotter.subplot(j)
803 lims = self._plotter.axes.get_xlim()
804 for row in range(linecat.nrow()):
805 # get_frequency returns MHz
806 base = { "GHz": 1000.0, "MHz": 1.0, "Hz": 1.0e-6 }
807 restf = linecat.get_frequency(row)/base[self._data.get_unit()]
808 c = 299792.458
809 freq = restf*(1.0-doppler/c)
810 if lims[0] < freq < lims[1]:
811 if location is None:
812 loc = 'bottom'
813 if row%2: loc='top'
814 else: loc = location
815 maxys = []
816 for line in self._plotter.axes.lines:
817 v = line._x
818 asc = v[0] < v[-1]
819
820 idx = None
821 if not asc:
822 if v[len(v)-1] <= freq <= v[0]:
823 i = len(v)-1
824 while i>=0 and v[i] < freq:
825 idx = i
826 i-=1
827 else:
828 if v[0] <= freq <= v[len(v)-1]:
829 i = 0
830 while i<len(v) and v[i] < freq:
831 idx = i
832 i+=1
833 if idx is not None:
834 lower = idx - deltachan
835 upper = idx + deltachan
836 if lower < 0: lower = 0
837 if upper > len(v): upper = len(v)
838 s = slice(lower, upper)
839 y = line._y[s]
840 maxy = ma.maximum(y)
841 if isinstance( maxy, float):
842 maxys.append(maxy)
843 if len(maxys):
844 peak = max(maxys)
845 if peak > self._plotter.axes.get_ylim()[1]:
846 loc = 'bottom'
847 else:
848 continue
849 self._plotter.vline_with_label(freq, peak,
850 linecat.get_name(row),
851 location=loc, rotate=rotate)
852 self._plotter.show(hardrefresh=False)
853
854
855 def set_selection(self, selection=None, refresh=True, **kw):
856 """
857 Parameters:
858 selection: a selector object (default unset the selection)
859 refresh: True (default) or False. If True, the plot is
860 replotted based on the new parameter setting(s).
861 Otherwise,the parameter(s) are set without replotting.
862 """
863 if selection is None:
864 # reset
865 if len(kw) == 0:
866 self._selection = selector()
867 else:
868 # try keywords
869 for k in kw:
870 if k not in selector.fields:
871 raise KeyError("Invalid selection key '%s', valid keys are %s" % (k, selector.fields))
872 self._selection = selector(**kw)
873 elif isinstance(selection, selector):
874 self._selection = selection
875 else:
876 raise TypeError("'selection' is not of type selector")
877
878 order = self._get_sortstring([self._panelling,self._stacking])
879 if order:
880 self._selection.set_order(order)
881 if refresh and self._data:
882 self.plot()
883
884 @asaplog_post_dec
885 def set_mask(self, mask=None, selection=None, refresh=True):
886 """
887 Set a plotting mask for a specific polarization.
888 This is useful for masking out 'noise' Pangle outside a source.
889 Parameters:
890 mask: a mask from scantable.create_mask
891 selection: the spectra to apply the mask to.
892 refresh: True (default) or False. If True, the plot is
893 replotted based on the new parameter setting(s).
894 Otherwise,the parameter(s) are set without replotting.
895 Example:
896 select = selector()
897 select.setpolstrings('Pangle')
898 plotter.set_mask(mymask, select)
899 """
900 if not self._data:
901 msg = "Can only set mask after a first call to plot()"
902 raise RuntimeError(msg)
903 if len(mask):
904 if isinstance(mask, list) or isinstance(mask, tuple):
905 self._usermask = array(mask)
906 else:
907 self._usermask = mask
908 if mask is None and selection is None:
909 self._usermask = []
910 self._maskselection = None
911 if isinstance(selection, selector):
912 self._maskselection = {'b': selection.get_beams(),
913 's': selection.get_scans(),
914 'i': selection.get_ifs(),
915 'p': selection.get_pols(),
916 't': [] }
917 else:
918 self._maskselection = None
919 if refresh: self.plot(self._data)
920
921 def _slice_indeces(self, data):
922 mn = self._minmaxx[0]
923 mx = self._minmaxx[1]
924 asc = data[0] < data[-1]
925 start=0
926 end = len(data)-1
927 inc = 1
928 if not asc:
929 start = len(data)-1
930 end = 0
931 inc = -1
932 # find min index
933 #while start > 0 and data[start] < mn:
934 # start+= inc
935 minind=start
936 for ind in xrange(start,end+inc,inc):
937 if data[ind] > mn: break
938 minind=ind
939 # find max index
940 #while end > 0 and data[end] > mx:
941 # end-=inc
942 #if end > 0: end +=1
943 maxind=end
944 for ind in xrange(end,start-inc,-inc):
945 if data[ind] < mx: break
946 maxind=ind
947 start=minind
948 end=maxind
949 if start > end:
950 return end,start+1
951 elif start < end:
952 return start,end+1
953 else:
954 return start,end
955
956 # reset methods
957 def _reset(self):
958 self._usermask = []
959 self._usermaskspectra = None
960 self._offset = None
961 self.set_selection(None, False)
962 self._reset_header()
963
964 def _reset_header(self):
965 self._headtext={'string': None, 'textobj': None}
966
967 def _reset_counter(self):
968 self._startrow = 0
969 self._ipanel = -1
970 self._reset_header()
971 self._panelrows = []
972 if self.casabar_exists():
973 self._plotter.figmgr.casabar.set_pagecounter(1)
974
975 def _reset_counters(self):
976 self._startrow = 0
977 self._ipanel = -1
978 self._panelrows = []
979
980 # scantable plot methods
981 @asaplog_post_dec
982 def plot(self, scan=None):
983 """
984 Plot a scantable.
985 Parameters:
986 scan: a scantable
987 Note:
988 If a scantable was specified in a previous call
989 to plot, no argument has to be given to 'replot'
990 NO checking is done that the abcissas of the scantable
991 are consistent e.g. all 'channel' or all 'velocity' etc.
992 """
993 if not self._data and not scan:
994 msg = "Input is not a scantable"
995 raise TypeError(msg)
996
997 self._assert_plotter(action="reload")
998 self._plotter.hold()
999 self._reset_counter()
1000 #self._plotter.clear()
1001 if scan:
1002 self.set_data(scan, refresh=False)
1003 self._plotter.palette(color=0,colormap=self._colormap,
1004 linestyle=0,linestyles=self._linestyles)
1005 self._plotter.legend(self._legendloc)
1006 self._plot(self._data)
1007 if self._minmaxy is not None:
1008 self._plotter.set_limits(ylim=self._minmaxy)
1009 if self.casabar_exists(): self._plotter.figmgr.casabar.enable_button()
1010 self._plotter.release()
1011 self._plotter.tidy()
1012 self._plotter.show(hardrefresh=False)
1013 return
1014
1015 def _plot(self, scan):
1016 savesel = scan.get_selection()
1017 sel = savesel + self._selection
1018 order = self._get_sortstring([self._panelling,self._stacking])
1019 if order:
1020 sel.set_order(order)
1021 scan.set_selection(sel)
1022 d = {'b': scan.getbeam, 's': scan.getscan,
1023 'i': scan.getif, 'p': scan.getpol, 't': scan.get_time,
1024 'r': int}#, '_r': int}
1025
1026 polmodes = dict(zip(sel.get_pols(), sel.get_poltypes()))
1027 # this returns either a tuple of numbers or a length (ncycles)
1028 # convert this into lengths
1029 n0,nstack0 = self._get_selected_n(scan)
1030 if isinstance(n0, int): n = n0
1031 else: n = len(n0)
1032 if isinstance(nstack0, int): nstack = nstack0
1033 else: nstack = len(nstack0)
1034 # In case of row stacking
1035 rowstack = False
1036 titlemode = self._panelling
1037 if self._stacking == "r" and self._panelling != "r":
1038 rowstack = True
1039 titlemode = '_r'
1040 nptot = n
1041 maxpanel, maxstack = 16,16
1042 if nstack > maxstack:
1043 msg ="Scan to be overlayed contains more than %d selections.\n" \
1044 "Selecting first %d selections..." % (maxstack, maxstack)
1045 asaplog.push(msg)
1046 asaplog.post('WARN')
1047 nstack = min(nstack,maxstack)
1048 #n = min(n-self._ipanel-1,maxpanel)
1049 n = n-self._ipanel-1
1050 # the number of panels in this page
1051 if self._rows and self._cols:
1052 n = min(n,self._rows*self._cols)
1053 else:
1054 n = min(n,maxpanel)
1055
1056 firstpage = (self._ipanel < 0)
1057 #ganged = False
1058 ganged = rcParams['plotter.ganged']
1059 if self._panelling == 'i':
1060 ganged = False
1061 if not firstpage:
1062 # not the first page just clear the axis
1063 nx = self._plotter.cols
1064 ipaxx = n - nx - 1 #the max panel id to supress x-label
1065 for ip in xrange(len(self._plotter.subplots)):
1066 self._plotter.subplot(ip)
1067 self._plotter.clear()
1068 self._plotter.axes.set_visible((ip<n))
1069 if ganged:
1070 self._plotter.axes.xaxis.label.set_visible((ip > ipaxx))
1071 if ip <= ipaxx:
1072 map(lambda x: x.set_visible(False), \
1073 self._plotter.axes.get_xticklabels())
1074 self._plotter.axes.yaxis.label.set_visible((ip % nx)==0)
1075 if ip % nx:
1076 map(lambda y: y.set_visible(False), \
1077 self._plotter.axes.get_yticklabels())
1078 elif (n > 1 and self._rows and self._cols):
1079 self._plotter.set_panels(rows=self._rows,cols=self._cols,
1080 nplots=n,margin=self._margins,
1081 ganged=ganged)
1082 else:
1083 self._plotter.set_panels(rows=n,cols=0,nplots=n,
1084 margin=self._margins,ganged=ganged)
1085 #r = 0
1086 r = self._startrow
1087 nr = scan.nrow()
1088 a0,b0 = -1,-1
1089 allxlim = []
1090 allylim = []
1091 #newpanel=True
1092 newpanel=False
1093 panelcount,stackcount = 0,0
1094 # If this is not the first page
1095 if r > 0:
1096 # panelling value of the prev page
1097 a0 = d[self._panelling](r-1)
1098 # set the initial stackcount large not to plot
1099 # the start row automatically
1100 stackcount = nstack
1101
1102 while r < nr:
1103 a = d[self._panelling](r)
1104 b = d[self._stacking](r)
1105 if a > a0 and panelcount < n:
1106 if n > 1:
1107 self._plotter.subplot(panelcount)
1108 self._plotter.palette(0)
1109 #title
1110 xlab = self._abcissa and self._abcissa[panelcount] \
1111 or scan._getabcissalabel()
1112 if self._offset and not self._abcissa:
1113 xlab += " (relative)"
1114 ylab = self._ordinate and self._ordinate[panelcount] \
1115 or scan._get_ordinate_label()
1116 self._plotter.set_axes('xlabel', xlab)
1117 self._plotter.set_axes('ylabel', ylab)
1118 #lbl = self._get_label(scan, r, self._panelling, self._title)
1119 lbl = self._get_label(scan, r, titlemode, self._title)
1120 if isinstance(lbl, list) or isinstance(lbl, tuple):
1121 if 0 <= panelcount < len(lbl):
1122 lbl = lbl[panelcount]
1123 else:
1124 # get default label
1125 #lbl = self._get_label(scan, r, self._panelling, None)
1126 lbl = self._get_label(scan, r, titlemode, None)
1127 self._plotter.set_axes('title',lbl)
1128 newpanel = True
1129 stackcount = 0
1130 panelcount += 1
1131 # save the start row to plot this panel for future revisit.
1132 if self._panelling != 'r' and \
1133 len(self._panelrows) < self._ipanel+1+panelcount:
1134 self._panelrows += [r]
1135
1136 #if (b > b0 or newpanel) and stackcount < nstack:
1137 if stackcount < nstack and (newpanel or \
1138 rowstack or (a == a0 and b > b0)):
1139 y = []
1140 if len(polmodes):
1141 y = scan._getspectrum(r, polmodes[scan.getpol(r)])
1142 else:
1143 y = scan._getspectrum(r)
1144 # flag application
1145 mr = scan._getflagrow(r)
1146 from numpy import ma, array
1147 if mr:
1148 y = ma.masked_array(y,mask=mr)
1149 else:
1150 m = scan._getmask(r)
1151 from numpy import logical_not, logical_and
1152 if self._maskselection and len(self._usermask) == len(m):
1153 if d[self._stacking](r) in self._maskselection[self._stacking]:
1154 m = logical_and(m, self._usermask)
1155 y = ma.masked_array(y,mask=logical_not(array(m,copy=False)))
1156
1157 x = array(scan._getabcissa(r))
1158 if self._offset:
1159 x += self._offset
1160 if self._minmaxx is not None:
1161 s,e = self._slice_indeces(x)
1162 x = x[s:e]
1163 y = y[s:e]
1164 if len(x) > 1024 and rcParams['plotter.decimate']:
1165 fac = len(x)/1024
1166 x = x[::fac]
1167 y = y[::fac]
1168 llbl = self._get_label(scan, r, self._stacking, self._lmap)
1169 if isinstance(llbl, list) or isinstance(llbl, tuple):
1170 if 0 <= stackcount < len(llbl):
1171 # use user label
1172 llbl = llbl[stackcount]
1173 else:
1174 # get default label
1175 llbl = self._get_label(scan, r, self._stacking, None)
1176 self._plotter.set_line(label=llbl)
1177 plotit = self._plotter.plot
1178 if self._hist: plotit = self._plotter.hist
1179 if len(x) > 0 and not mr:
1180 plotit(x,y)
1181 xlim= self._minmaxx or [min(x),max(x)]
1182 allxlim += xlim
1183 ylim= self._minmaxy or [ma.minimum(y),ma.maximum(y)]
1184 allylim += ylim
1185 else:
1186 xlim = self._minmaxx or []
1187 allxlim += xlim
1188 ylim= self._minmaxy or []
1189 allylim += ylim
1190 stackcount += 1
1191 a0=a
1192 b0=b
1193 # last in colour stack -> autoscale x
1194 if stackcount == nstack and len(allxlim) > 0:
1195 allxlim.sort()
1196 self._plotter.subplots[panelcount-1]['axes'].set_xlim([allxlim[0],allxlim[-1]])
1197 if ganged:
1198 allxlim = [allxlim[0],allxlim[-1]]
1199 else:
1200 # clear
1201 allxlim =[]
1202
1203 newpanel = False
1204 #a0=a
1205 #b0=b
1206 # ignore following rows
1207 if (panelcount == n and stackcount == nstack) or (r == nr-1):
1208 # last panel -> autoscale y if ganged
1209 #if rcParams['plotter.ganged'] and len(allylim) > 0:
1210 if ganged and len(allylim) > 0:
1211 allylim.sort()
1212 self._plotter.set_limits(ylim=[allylim[0],allylim[-1]])
1213 break
1214 r+=1 # next row
1215
1216 # save the current counter for multi-page plotting
1217 self._startrow = r+1
1218 self._ipanel += panelcount
1219 if self.casabar_exists():
1220 if self._ipanel >= nptot-1:
1221 self._plotter.figmgr.casabar.disable_next()
1222 else:
1223 self._plotter.figmgr.casabar.enable_next()
1224 if self._ipanel + 1 - panelcount > 0:
1225 self._plotter.figmgr.casabar.enable_prev()
1226 else:
1227 self._plotter.figmgr.casabar.disable_prev()
1228
1229 #reset the selector to the scantable's original
1230 scan.set_selection(savesel)
1231
1232 #temporary switch-off for older matplotlib
1233 #if self._fp is not None:
1234 if self._fp is not None and \
1235 getattr(self._plotter.figure,'findobj',False):
1236 for o in self._plotter.figure.findobj(Text):
1237 if not self._headtext['textobj'] or \
1238 not (o in self._headtext['textobj']):
1239 o.set_fontproperties(self._fp)
1240
1241 def _get_sortstring(self, lorders):
1242 d0 = {'s': 'SCANNO', 'b': 'BEAMNO', 'i':'IFNO',
1243 'p': 'POLNO', 'c': 'CYCLENO', 't' : 'TIME', 'r':None, '_r':None }
1244 if not (type(lorders) == list) and not (type(lorders) == tuple):
1245 return None
1246 if len(lorders) > 0:
1247 lsorts = []
1248 for order in lorders:
1249 if order == "r":
1250 # don't sort if row panelling/stacking
1251 return None
1252 ssort = d0[order]
1253 if ssort:
1254 lsorts.append(ssort)
1255 return lsorts
1256 return None
1257
1258 def _get_selected_n(self, scan):
1259 d1 = {'b': scan.getbeamnos, 's': scan.getscannos,
1260 'i': scan.getifnos, 'p': scan.getpolnos, 't': scan.ncycle,
1261 'r': scan.nrow}#, '_r': False}
1262 d2 = { 'b': self._selection.get_beams(),
1263 's': self._selection.get_scans(),
1264 'i': self._selection.get_ifs(),
1265 'p': self._selection.get_pols(),
1266 't': self._selection.get_cycles(),
1267 'r': False}#, '_r': 1}
1268 n = d2[self._panelling] or d1[self._panelling]()
1269 nstack = d2[self._stacking] or d1[self._stacking]()
1270 # handle row panelling/stacking
1271 if self._panelling == 'r':
1272 nstack = 1
1273 elif self._stacking == 'r':
1274 n = 1
1275 return n,nstack
1276
1277 def _get_label(self, scan, row, mode, userlabel=None):
1278 if isinstance(userlabel, list) and len(userlabel) == 0:
1279 userlabel = " "
1280 pms = dict(zip(self._selection.get_pols(),self._selection.get_poltypes()))
1281 if len(pms):
1282 poleval = scan._getpollabel(scan.getpol(row),pms[scan.getpol(row)])
1283 else:
1284 poleval = scan._getpollabel(scan.getpol(row),scan.poltype())
1285 d = {'b': "Beam "+str(scan.getbeam(row)),
1286 #'s': scan._getsourcename(row),
1287 's': "Scan "+str(scan.getscan(row))+\
1288 " ("+str(scan._getsourcename(row))+")",
1289 'i': "IF"+str(scan.getif(row)),
1290 'p': poleval,
1291 't': str(scan.get_time(row)),
1292 'r': "row "+str(row),
1293 #'_r': str(scan.get_time(row))+",\nIF"+str(scan.getif(row))+", "+poleval+", Beam"+str(scan.getbeam(row)) }
1294 '_r': "" }
1295 return userlabel or d[mode]
1296
1297 def plotazel(self, scan=None, outfile=None):
1298 """
1299 plot azimuth and elevation versus time of a scantable
1300 """
1301 visible = rcParams['plotter.gui']
1302 from matplotlib import pylab as PL
1303 from matplotlib.dates import DateFormatter
1304 from pytz import timezone
1305 from matplotlib.dates import HourLocator, MinuteLocator,SecondLocator, DayLocator
1306 from matplotlib.ticker import MultipleLocator
1307 from numpy import array, pi
1308 if not visible or not self._visible:
1309 PL.ioff()
1310 from matplotlib.backends.backend_agg import FigureCanvasAgg
1311 PL.gcf().canvas.switch_backends(FigureCanvasAgg)
1312 self._data = scan
1313 dates = self._data.get_time(asdatetime=True)
1314 t = PL.date2num(dates)
1315 tz = timezone('UTC')
1316 PL.cla()
1317 PL.ioff()
1318 PL.clf()
1319 # Adjust subplot margins
1320 if not self._margins or len(self._margins) != 6:
1321 self.set_margin(refresh=False)
1322 lef, bot, rig, top, wsp, hsp = self._margins
1323 PL.gcf().subplots_adjust(left=lef,bottom=bot,right=rig,top=top,
1324 wspace=wsp,hspace=hsp)
1325
1326 tdel = max(t) - min(t)
1327 ax = PL.subplot(2,1,1)
1328 el = array(self._data.get_elevation())*180./pi
1329 PL.ylabel('El [deg.]')
1330 dstr = dates[0].strftime('%Y/%m/%d')
1331 if tdel > 1.0:
1332 dstr2 = dates[len(dates)-1].strftime('%Y/%m/%d')
1333 dstr = dstr + " - " + dstr2
1334 majloc = DayLocator()
1335 minloc = HourLocator(range(0,23,12))
1336 timefmt = DateFormatter("%b%d")
1337 elif tdel > 24./60.:
1338 timefmt = DateFormatter('%H:%M')
1339 majloc = HourLocator()
1340 minloc = MinuteLocator(30)
1341 else:
1342 timefmt = DateFormatter('%H:%M')
1343 majloc = MinuteLocator(interval=5)
1344 minloc = SecondLocator(30)
1345
1346 PL.title(dstr)
1347 if tdel == 0.0:
1348 th = (t - PL.floor(t))*24.0
1349 PL.plot(th,el,'o',markersize=2, markerfacecolor='b', markeredgecolor='b')
1350 else:
1351 PL.plot_date(t,el,'o', markersize=2, markerfacecolor='b', markeredgecolor='b',tz=tz)
1352 #ax.grid(True)
1353 ax.xaxis.set_major_formatter(timefmt)
1354 ax.xaxis.set_major_locator(majloc)
1355 ax.xaxis.set_minor_locator(minloc)
1356 ax.yaxis.grid(True)
1357 yloc = MultipleLocator(30)
1358 ax.set_ylim(0,90)
1359 ax.yaxis.set_major_locator(yloc)
1360 if tdel > 1.0:
1361 labels = ax.get_xticklabels()
1362 # PL.setp(labels, fontsize=10, rotation=45)
1363 PL.setp(labels, fontsize=10)
1364
1365 # Az plot
1366 az = array(self._data.get_azimuth())*180./pi
1367 if min(az) < 0:
1368 for irow in range(len(az)):
1369 if az[irow] < 0: az[irow] += 360.0
1370
1371 ax2 = PL.subplot(2,1,2)
1372 #PL.xlabel('Time (UT [hour])')
1373 PL.ylabel('Az [deg.]')
1374 if tdel == 0.0:
1375 PL.plot(th,az,'o',markersize=2, markeredgecolor='b',markerfacecolor='b')
1376 else:
1377 PL.plot_date(t,az,'o', markersize=2,markeredgecolor='b',markerfacecolor='b',tz=tz)
1378 ax2.xaxis.set_major_formatter(timefmt)
1379 ax2.xaxis.set_major_locator(majloc)
1380 ax2.xaxis.set_minor_locator(minloc)
1381 #ax2.grid(True)
1382 ax2.set_ylim(0,360)
1383 ax2.yaxis.grid(True)
1384 #hfmt = DateFormatter('%H')
1385 #hloc = HourLocator()
1386 yloc = MultipleLocator(60)
1387 ax2.yaxis.set_major_locator(yloc)
1388 if tdel > 1.0:
1389 labels = ax2.get_xticklabels()
1390 PL.setp(labels, fontsize=10)
1391 PL.xlabel('Time (UT [day])')
1392 else:
1393 PL.xlabel('Time (UT [hour])')
1394
1395 PL.ion()
1396 PL.draw()
1397 if matplotlib.get_backend() == 'Qt4Agg': PL.gcf().show()
1398 if (outfile is not None):
1399 PL.savefig(outfile)
1400
1401
1402 def plotpointing2(self, scan=None, colorby='', showline=False, projection=''):
1403 """
1404 plot telescope pointings
1405 Parameters:
1406 infile : input filename or scantable instance
1407 colorby : change color by either
1408 'type'(source type)|'scan'|'if'|'pol'|'beam'
1409 showline : show dotted line
1410 projection : projection type either
1411 ''(no projection [deg])|'coord'(not implemented)
1412 """
1413 from numpy import array, pi
1414 from asap import scantable
1415 # check for scantable
1416 if isinstance(scan, scantable):
1417 if self._data is not None:
1418 if scan != self._data:
1419 self._data = scan
1420 # reset
1421 self._reset()
1422 else:
1423 self._data = scan
1424 self._reset()
1425 if not self._data:
1426 msg = "Input is not a scantable"
1427 raise TypeError(msg)
1428 # check for color mode
1429 validtypes=['type','scan','if','pol', 'beam']
1430 stype = None
1431 if (colorby in validtypes):
1432 stype = colorby[0]
1433 elif len(colorby) > 0:
1434 msg = "Invalid choice of 'colorby' (choices: %s)" % str(validtypes)
1435 raise ValueError(msg)
1436 self._assert_plotter(action="reload")
1437 self._plotter.hold()
1438 self._reset_counter()
1439 if self.casabar_exists():
1440 self._plotter.figmgr.casabar.disable_button()
1441 # for now, only one plot
1442 self._plotter.set_panels(rows=1,cols=1)
1443 # first panel
1444 self._plotter.subplot(0)
1445 # first color and linestyles
1446 self._plotter.palette(0)
1447 self.gca().set_aspect('equal')
1448 basesel = scan.get_selection()
1449 attrback = self._plotter.get_line()
1450 marker = "o"
1451 if showline:
1452 basesel.set_order(["TIME"])
1453 scan.set_selection(basesel)
1454 if not (stype in ["t", "s"]):
1455 marker += ":"
1456 self._plotter.set_line(markersize=3, markeredgewidth=0)
1457
1458 if not stype:
1459 selIds = [""] # cheating
1460 sellab = "all points"
1461 elif stype == 't':
1462 selIds = range(15)
1463 sellab = "src type "
1464 else:
1465 selIds = getattr(self._data,'get'+colorby+'nos')()
1466 sellab = colorby.upper()
1467 selFunc = "set_"+colorby+"s"
1468 for idx in selIds:
1469 sel = selector() + basesel
1470 if stype:
1471 bid = getattr(basesel,'get_'+colorby+"s")()
1472 if (len(bid) > 0) and (not idx in bid):
1473 # base selection doesn't contain idx
1474 # Note summation of selector is logical sum if
1475 continue
1476 getattr(sel, selFunc)([idx])
1477 if not sel.is_empty():
1478 try:
1479 self._data.set_selection(sel)
1480 except RuntimeError, instance:
1481 if stype == 't' and str(instance).startswith("Selection contains no data."):
1482 continue
1483 else:
1484 self._data.set_selection(basesel)
1485 raise RuntimeError, instance
1486 if self._data.nrow() == 0:
1487 self._data.set_selection(basesel)
1488 continue
1489 print "Plotting direction of %s = %s" % (colorby, str(idx))
1490 # getting data to plot
1491 dir = array(self._data.get_directionval()).transpose()
1492 ra = dir[0]*180./pi
1493 dec = dir[1]*180./pi
1494 # actual plot
1495 self._plotter.set_line(label=(sellab+str(idx)))
1496 self._plotter.plot(ra,dec,marker)
1497
1498 # restore original selection
1499 self._data.set_selection(basesel)
1500 # need to plot scan pattern explicitly
1501 if showline and (stype in ["t", "s"]):
1502 dir = array(self._data.get_directionval()).transpose()
1503 ra = dir[0]*180./pi
1504 dec = dir[1]*180./pi
1505 self._plotter.set_line(label="scan pattern")
1506 self._plotter.plot(ra,dec,":")
1507 # set color for only this line
1508 self._plotter.lines[-1][0].set_color("gray")
1509
1510 xlab = 'RA [deg.]'
1511 ylab = 'Declination [deg.]'
1512 self._plotter.set_axes('xlabel', xlab)
1513 self._plotter.set_axes('ylabel', ylab)
1514 self._plotter.set_axes('title', 'Telescope pointings')
1515 if stype: self._plotter.legend(self._legendloc)
1516 else: self._plotter.legend(None)
1517 # reverse x-axis
1518 xmin, xmax = self.gca().get_xlim()
1519 self._plotter.set_limits(xlim=[xmax,xmin])
1520
1521 self._plotter.release()
1522 self._plotter.show(hardrefresh=False)
1523 # reset line settings
1524 self._plotter.set_line(**attrback)
1525 return
1526
1527 def plotpointing(self, scan=None, outfile=None):
1528 """
1529 plot telescope pointings
1530 """
1531 visible = rcParams['plotter.gui']
1532 from matplotlib import pylab as PL
1533 from numpy import array, pi
1534 if not visible or not self._visible:
1535 PL.ioff()
1536 from matplotlib.backends.backend_agg import FigureCanvasAgg
1537 PL.gcf().canvas.switch_backends(FigureCanvasAgg)
1538 self._data = scan
1539 dir = array(self._data.get_directionval()).transpose()
1540 ra = dir[0]*180./pi
1541 dec = dir[1]*180./pi
1542 PL.cla()
1543 #PL.ioff()
1544 PL.clf()
1545 # Adjust subplot margins
1546 if not self._margins or len(self._margins) != 6:
1547 self.set_margin(refresh=False)
1548 lef, bot, rig, top, wsp, hsp = self._margins
1549 PL.gcf().subplots_adjust(left=lef,bottom=bot,right=rig,top=top,
1550 wspace=wsp,hspace=hsp)
1551 ax = PL.gca()
1552 #ax = PL.axes([0.1,0.1,0.8,0.8])
1553 #ax = PL.axes([0.1,0.1,0.8,0.8])
1554 ax.set_aspect('equal')
1555 PL.plot(ra, dec, 'b,')
1556 PL.xlabel('RA [deg.]')
1557 PL.ylabel('Declination [deg.]')
1558 PL.title('Telescope pointings')
1559 [xmin,xmax,ymin,ymax] = PL.axis()
1560 PL.axis([xmax,xmin,ymin,ymax])
1561 PL.ion()
1562 PL.draw()
1563 if matplotlib.get_backend() == 'Qt4Agg': PL.gcf().show()
1564 if (outfile is not None):
1565 PL.savefig(outfile)
1566
1567 # plot total power data
1568 # plotting in time is not yet implemented..
1569 @asaplog_post_dec
1570 def plottp(self, scan=None):
1571 from asap import scantable
1572 if not self._data and not scan:
1573 msg = "Input is not a scantable"
1574 raise TypeError(msg)
1575 if isinstance(scan, scantable):
1576 if self._data is not None:
1577 if scan != self._data:
1578 self._data = scan
1579 # reset
1580 self._reset()
1581 else:
1582 self._data = scan
1583 self._reset()
1584 # ranges become invalid when abcissa changes?
1585 #if self._abcunit and self._abcunit != self._data.get_unit():
1586 # self._minmaxx = None
1587 # self._minmaxy = None
1588 # self._abcunit = self._data.get_unit()
1589
1590 self._assert_plotter(action="reload")
1591 self._plotter.hold()
1592 self._plotter.clear()
1593 # Adjust subplot margins
1594 if not self._margins or len(self._margins) !=6:
1595 self.set_margin(refresh=False)
1596 lef, bot, rig, top, wsp, hsp = self._margins
1597 self._plotter.figure.subplots_adjust(
1598 left=lef,bottom=bot,right=rig,top=top,wspace=wsp,hspace=hsp)
1599 if self.casabar_exists(): self._plotter.figmgr.casabar.disable_button()
1600 self._plottp(self._data)
1601 if self._minmaxy is not None:
1602 self._plotter.set_limits(ylim=self._minmaxy)
1603 self._plotter.release()
1604 self._plotter.tidy()
1605 self._plotter.show(hardrefresh=False)
1606 return
1607
1608 def _plottp(self,scan):
1609 """
1610 private method for plotting total power data
1611 """
1612 from numpy import ma, array, arange, logical_not
1613 r=0
1614 nr = scan.nrow()
1615 a0,b0 = -1,-1
1616 allxlim = []
1617 allylim = []
1618 y=[]
1619 self._plotter.set_panels()
1620 self._plotter.palette(0)
1621 #title
1622 #xlab = self._abcissa and self._abcissa[panelcount] \
1623 # or scan._getabcissalabel()
1624 #ylab = self._ordinate and self._ordinate[panelcount] \
1625 # or scan._get_ordinate_label()
1626 xlab = self._abcissa or 'row number' #or Time
1627 ylab = self._ordinate or scan._get_ordinate_label()
1628 self._plotter.set_axes('xlabel',xlab)
1629 self._plotter.set_axes('ylabel',ylab)
1630 lbl = self._get_label(scan, r, 's', self._title)
1631 if isinstance(lbl, list) or isinstance(lbl, tuple):
1632 # if 0 <= panelcount < len(lbl):
1633 # lbl = lbl[panelcount]
1634 # else:
1635 # get default label
1636 lbl = self._get_label(scan, r, self._panelling, None)
1637 self._plotter.set_axes('title',lbl)
1638 y=array(scan._get_column(scan._getspectrum,-1))
1639 m = array(scan._get_column(scan._getmask,-1))
1640 y = ma.masked_array(y,mask=logical_not(array(m,copy=False)))
1641 x = arange(len(y))
1642 # try to handle spectral data somewhat...
1643 l,m = y.shape
1644 if m > 1:
1645 y=y.mean(axis=1)
1646 plotit = self._plotter.plot
1647 llbl = self._get_label(scan, r, self._stacking, None)
1648 self._plotter.set_line(label=llbl)
1649 if len(x) > 0:
1650 plotit(x,y)
1651
1652
1653 # printing header information
1654 @asaplog_post_dec
1655 def print_header(self, plot=True, fontsize=9, logger=False, selstr='', extrastr=''):
1656 """
1657 print data (scantable) header on the plot and/or logger.
1658 To plot the header on the plot, this method should be called after
1659 plotting spectra by the method, asapplotter.plot.
1660 Parameters:
1661 plot: whether or not print header info on the plot.
1662 fontsize: header font size (valid only plot=True)
1663 logger: whether or not print header info on the logger.
1664 selstr: additional selection string (not verified)
1665 extrastr: additional string to print at the beginning (not verified)
1666 """
1667 if not plot and not logger:
1668 return
1669 if not self._data:
1670 raise RuntimeError("No scantable has been set yet.")
1671 # Now header will be printed on plot and/or logger.
1672 # Get header information and format it.
1673 ssum=self._data._list_header()
1674 # Print Observation header to the upper-left corner of plot
1675 headstr=[ssum[0:ssum.find('Obs. Type:')]]
1676 headstr.append(ssum[ssum.find('Obs. Type:'):ssum.find('Flux Unit:')])
1677 if extrastr != '':
1678 headstr[0]=extrastr+'\n'+headstr[0]
1679 self._headtext['extrastr'] = extrastr
1680 if selstr != '':
1681 selstr += '\n'
1682 self._headtext['selstr'] = selstr
1683 ssel=(selstr+self._data.get_selection().__str__()+self._selection.__str__() or 'none')
1684 headstr.append('***Selections***\n'+ssel)
1685
1686 if plot:
1687 errmsg = "Can plot header only after the first call to plot()."
1688 self._assert_plotter(action="halt",errmsg=errmsg)
1689 self._plotter.hold()
1690 self._header_plot(headstr,fontsize=fontsize)
1691 #import time
1692 #self._plotter.figure.text(0.99,0.01,
1693 # time.strftime("%a %d %b %Y %H:%M:%S %Z"),
1694 # horizontalalignment='right',
1695 # verticalalignment='bottom',fontsize=8)
1696 self._plotter.release()
1697 if logger:
1698 selstr = "Selections: "+ssel
1699 asaplog.push("----------------\n Plot Summary\n----------------")
1700 asaplog.push(extrastr)
1701 asaplog.push(ssum[0:ssum.find('Selection:')]\
1702 + selstr)
1703 self._headtext['string'] = headstr
1704 del ssel, ssum, headstr
1705
1706 def _header_plot(self, texts, fontsize=9):
1707 self._headtext['textobj']=[]
1708 nstcol=len(texts)
1709 for i in range(nstcol):
1710 self._headtext['textobj'].append(
1711 self._plotter.figure.text(0.03+float(i)/nstcol,0.98,
1712 texts[i],
1713 horizontalalignment='left',
1714 verticalalignment='top',
1715 fontsize=fontsize))
1716
1717 def clear_header(self):
1718 if not self._headtext['textobj']:
1719 asaplog.push("No header has been plotted. Exit without any operation")
1720 asaplog.post("WARN")
1721 elif self._assert_plotter(action="status"):
1722 self._plotter.hold()
1723 for textobj in self._headtext['textobj']:
1724 #if textobj.get_text() in self._headstring:
1725 try:
1726 textobj.remove()
1727 except NotImplementedError:
1728 self._plotter.figure.texts.pop(self._plotter.figure.texts.index(textobj))
1729 self._plotter.release()
1730 self._reset_header()
1731
1732 # plot spectra by pointing
1733 @asaplog_post_dec
1734 def plotgrid(self, scan=None,center=None,spacing=None,rows=None,cols=None):
1735 """
1736 Plot spectra based on direction.
1737
1738 Parameters:
1739 scan: a scantable to plot
1740 center: the grid center direction (a list) of plots in the
1741 unit of DIRECTION column.
1742 (default) the center of map region
1743 spacing: a list of horizontal (R.A.) and vertical (Dec.)
1744 spacing in the unit of DIRECTION column.
1745 (default) Calculated by the extent of map region and
1746 the number of rows and cols to cover
1747 rows: number of panels (grid points) in horizontal direction
1748 cols: number of panels (grid points) in vertical direction
1749
1750 Note:
1751 - Only the first IFNO, POLNO, and BEAM in the scantable will be
1752 plotted.
1753 - This method doesn't re-grid and average spectra in scantable. Use
1754 asapgrid module to re-grid spectra before plotting with this method.
1755 Only the first spectrum is plotted in case there are multiple
1756 spectra which belong to a grid.
1757 """
1758 from asap import scantable
1759 from numpy import array, ma, cos
1760 if not self._data and not scan:
1761 msg = "No scantable is specified to plot"
1762 raise TypeError(msg)
1763 if scan:
1764 self.set_data(scan, refresh=False)
1765 del scan
1766
1767 # Rows and cols
1768 if rows:
1769 self._rows = int(rows)
1770 else:
1771 msg = "Number of rows to plot are not specified. "
1772 if self._rows:
1773 msg += "Using previous value = %d" % (self._rows)
1774 asaplog.push(msg)
1775 else:
1776 self._rows = 1
1777 msg += "Setting rows = %d" % (self._rows)
1778 asaplog.post()
1779 asaplog.push(msg)
1780 asaplog.post("WARN")
1781 if cols:
1782 self._cols = int(cols)
1783 else:
1784 msg = "Number of cols to plot are not specified. "
1785 if self._cols:
1786 msg += "Using previous value = %d" % (self._cols)
1787 asaplog.push(msg)
1788 else:
1789 self._cols = 1
1790 msg += "Setting cols = %d" % (self._cols)
1791 asaplog.post()
1792 asaplog.push(msg)
1793 asaplog.post("WARN")
1794
1795 # Center and spacing
1796 dirarr = array(self._data.get_directionval()).transpose()
1797 print "Pointing range: (x, y) = (%f - %f, %f - %f)" %\
1798 (dirarr[0].min(),dirarr[0].max(),dirarr[1].min(),dirarr[1].max())
1799 dircent = [0.5*(dirarr[0].max() + dirarr[0].min()),
1800 0.5*(dirarr[1].max() + dirarr[1].min())]
1801 del dirarr
1802 if center is None:
1803 #asaplog.post()
1804 asaplog.push("Grid center is not specified. Automatically calculated from pointing center.")
1805 #asaplog.post("WARN")
1806 #center = [dirarr[0].mean(), dirarr[1].mean()]
1807 center = dircent
1808 elif (type(center) in (list, tuple)) and len(center) > 1:
1809 from numpy import pi
1810 # make sure center_x is in +-pi of pointing center
1811 # (assumes dirs are in rad)
1812 rotnum = round(abs(center[0] - dircent[0])/(2*pi))
1813 if center[0] < dircent[0]: rotnum *= -1
1814 cenx = center[0] - rotnum*2*pi
1815 center = [cenx, center[1]]
1816 else:
1817 msg = "Direction of grid center should be a list of float (R.A., Dec.)"
1818 raise ValueError, msg
1819 asaplog.push("Grid center: (%f, %f) " % (center[0],center[1]))
1820
1821 if spacing is None:
1822 #asaplog.post()
1823 asaplog.push("Grid spacing not specified. Automatically calculated from map coverage")
1824 #asaplog.post("WARN")
1825 # automatically get spacing
1826 dirarr = array(self._data.get_directionval()).transpose()
1827 wx = 2. * max(abs(dirarr[0].max()-center[0]),
1828 abs(dirarr[0].min()-center[0]))
1829 wy = 2. * max(abs(dirarr[1].max()-center[1]),
1830 abs(dirarr[1].min()-center[1]))
1831 ## slightly expand area to plot the edges
1832 #wx *= 1.1
1833 #wy *= 1.1
1834 xgrid = wx/max(self._cols-1.,1.)
1835 #xgrid = wx/float(max(self._cols,1.))
1836 xgrid *= cos(center[1])
1837 ygrid = wy/max(self._rows-1.,1.)
1838 #ygrid = wy/float(max(self._rows,1.))
1839 # single pointing (identical R.A. and/or Dec. for all spectra.)
1840 if xgrid == 0:
1841 xgrid = 1.
1842 if ygrid == 0:
1843 ygrid = 1.
1844 # spacing should be negative to transpose plot
1845 spacing = [- xgrid, - ygrid]
1846 del dirarr, xgrid, ygrid
1847 #elif isinstance(spacing, str):
1848 # # spacing is a quantity
1849 elif (type(spacing) in (list, tuple)) and len(spacing) > 1:
1850 for i in xrange(2):
1851 val = spacing[i]
1852 if not isinstance(val, float):
1853 raise TypeError("spacing should be a list of float")
1854 if val > 0.:
1855 spacing[i] = -val
1856 spacing = spacing[0:2]
1857 else:
1858 msg = "Invalid spacing."
1859 raise TypeError(msg)
1860 asaplog.push("Spacing: (%f, %f) (projected)" % (spacing[0],spacing[1]))
1861
1862 ntotpl = self._rows * self._cols
1863 ifs = self._data.getifnos()
1864 if len(ifs) > 1:
1865 msg = "Found multiple IFs in scantable. Only the first IF (IFNO=%d) will be plotted." % ifs[0]
1866 asaplog.post()
1867 asaplog.push(msg)
1868 asaplog.post("WARN")
1869 pols = self._data.getpolnos()
1870 if len(pols) > 1:
1871 msg = "Found multiple POLs in scantable. Only the first POL (POLNO=%d) will be plotted." % pols[0]
1872 asaplog.post()
1873 asaplog.push(msg)
1874 asaplog.post("WARN")
1875 beams = self._data.getbeamnos()
1876 if len(beams) > 1:
1877 msg = "Found multiple BEAMs in scantable. Only the first BEAM (BEAMNO=%d) will be plotted." % beams[0]
1878 asaplog.post()
1879 asaplog.push(msg)
1880 asaplog.post("WARN")
1881 self._data.set_selection(ifs=[ifs[0]],pols=[pols[0]],beams=[beams[0]])
1882 if self._data.nrow() > ntotpl:
1883 msg = "Scantable is finely sampled than plotting grids. "\
1884 + "Only the first spectrum is plotted in each grid."
1885 asaplog.post()
1886 asaplog.push(msg)
1887 asaplog.post("WARN")
1888
1889 self._assert_plotter(action="reload")
1890 self._plotter.hold()
1891 self._reset_counter()
1892 self._plotter.legend()
1893
1894 # Adjust subplot margins
1895 if not self._margins or len(self._margins) !=6:
1896 self.set_margin(refresh=False)
1897 self._plotter.set_panels(rows=self._rows,cols=self._cols,
1898 nplots=ntotpl,margin=self._margins,ganged=True)
1899 if self.casabar_exists():
1900 self._plotter.figmgr.casabar.enable_button()
1901 # Plot helper
1902 from asap._asap import plothelper as plhelper
1903 ph = plhelper(self._data)
1904 ph.set_gridval(self._cols, self._rows, spacing[0], spacing[1],
1905 center[0], center[1], epoch="J2000", projname="SIN")
1906 # Actual plot
1907 npl = 0
1908 for irow in range(self._data.nrow()):
1909 (ix, iy) = ph.get_gpos(irow)
1910 #print("asapplotter.plotgrid: (ix, iy) = (%f, %f)" % (ix, iy))
1911 if ix < 0 or ix >= self._cols:
1912 #print "Row %d : Out of X-range (x = %f) ... skipped" % (irow, pos[0])
1913 continue
1914 ix = int(ix)
1915 if iy < 0 or iy >= self._rows:
1916 #print "Row %d : Out of Y-range (y = %f) ... skipped" % (irow,pos[1])
1917 continue
1918 iy = int(iy)
1919 ipanel = ix + iy*self._rows
1920 #print("Resolved panel Id (%d, %d): %d" % (ix, iy, ipanel))
1921 if len(self._plotter.subplots[ipanel]['lines']) > 0:
1922 #print "Row %d : panel %d lready plotted ... skipped" % (irow,ipanel)
1923 # a spectrum already plotted in the panel
1924 continue
1925 # Plotting this row
1926 #print "PLOTTING row %d (panel=%d)" % (irow, ipanel)
1927 npl += 1
1928 self._plotter.subplot(ipanel)
1929 self._plotter.palette(0,colormap=self._colormap, \
1930 linestyle=0,linestyles=self._linestyles)
1931 xlab = self._abcissa and self._abcissa[ipanel] \
1932 or self._data._getabcissalabel(irow)
1933 if self._offset and not self._abcissa:
1934 xlab += " (relative)"
1935 ylab = self._ordinate and self._ordinate[ipanel] \
1936 or self._data._get_ordinate_label()
1937 self._plotter.set_axes('xlabel', xlab)
1938 self._plotter.set_axes('ylabel', ylab)
1939 lbl = self._data.get_direction(irow)
1940 self._plotter.set_axes('title',lbl)
1941
1942 y = self._data._getspectrum(irow)
1943 # flag application
1944 mr = self._data._getflagrow(irow)
1945 if mr: # FLAGROW=True
1946 y = ma.masked_array(y,mask=mr)
1947 else:
1948 m = self._data._getmask(irow)
1949 from numpy import logical_not, logical_and
1950 ### user mask is not available so far
1951 #if self._maskselection and len(self._usermask) == len(m):
1952 # if d[self._stacking](irow) in self._maskselection[self._stacking]:
1953 # m = logical_and(m, self._usermask)
1954 y = ma.masked_array(y,mask=logical_not(array(m,copy=False)))
1955
1956 x = array(self._data._getabcissa(irow))
1957 if self._offset:
1958 x += self._offset
1959 if self._minmaxx is not None:
1960 s,e = self._slice_indeces(x)
1961 x = x[s:e]
1962 y = y[s:e]
1963 if len(x) > 1024 and rcParams['plotter.decimate']:
1964 fac = len(x)/1024
1965 x = x[::fac]
1966 y = y[::fac]
1967 self._plotter.set_line(label=lbl)
1968 plotit = self._plotter.plot
1969 if self._hist: plotit = self._plotter.hist
1970 if len(x) > 0 and not mr:
1971 plotit(x,y)
1972# xlim= self._minmaxx or [min(x),max(x)]
1973# allxlim += xlim
1974# ylim= self._minmaxy or [ma.minimum(y),ma.maximum(y)]
1975# allylim += ylim
1976# else:
1977# xlim = self._minmaxx or []
1978# allxlim += xlim
1979# ylim= self._minmaxy or []
1980# allylim += ylim
1981
1982 if npl >= ntotpl:
1983 break
1984
1985 if self._minmaxy is not None:
1986 self._plotter.set_limits(ylim=self._minmaxy)
1987 self._plotter.release()
1988 self._plotter.tidy()
1989 self._plotter.show(hardrefresh=False)
1990 return
Note: See TracBrowser for help on using the repository browser.