source: trunk/python/asapplotter.py@ 1226

Last change on this file since 1226 was 1217, checked in by mar637, 18 years ago

Merge from Release2.1.0b tag

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 28.6 KB
RevLine 
[947]1from asap import rcParams, print_log, selector
[1146]2from asap import NUM
[1153]3import matplotlib.axes
[1217]4import sre
[203]5
6class asapplotter:
[226]7 """
8 The ASAP plotter.
9 By default the plotter is set up to plot polarisations
10 'colour stacked' and scantables across panels.
11 Note:
12 Currenly it only plots 'spectra' not Tsys or
13 other variables.
14 """
[734]15 def __init__(self, visible=None):
16 self._visible = rcParams['plotter.gui']
17 if visible is not None:
18 self._visible = visible
[710]19 self._plotter = self._newplotter()
20
[554]21 self._panelling = None
22 self._stacking = None
23 self.set_panelling()
24 self.set_stacking()
[377]25 self._rows = None
26 self._cols = None
[203]27 self._autoplot = False
[525]28 self._minmaxx = None
29 self._minmaxy = None
[710]30 self._datamask = None
[203]31 self._data = None
[607]32 self._lmap = None
[226]33 self._title = None
[257]34 self._ordinate = None
35 self._abcissa = None
[709]36 self._abcunit = None
[920]37 self._usermask = []
38 self._maskselection = None
39 self._selection = selector()
[1023]40 self._hist = rcParams['plotter.histogram']
41
[920]42 def _translate(self, instr):
43 keys = "s b i p t".split()
44 if isinstance(instr, str):
45 for key in keys:
46 if instr.lower().startswith(key):
47 return key
48 return None
49
[710]50 def _newplotter(self):
51 if self._visible:
52 from asap.asaplotgui import asaplotgui as asaplot
53 else:
54 from asap.asaplot import asaplot
55 return asaplot()
56
57
[935]58 def plot(self, scan=None):
[203]59 """
[920]60 Plot a scantable.
[203]61 Parameters:
[920]62 scan: a scantable
[203]63 Note:
[920]64 If a scantable was specified in a previous call
[203]65 to plot, no argument has to be given to 'replot'
[920]66 NO checking is done that the abcissas of the scantable
[203]67 are consistent e.g. all 'channel' or all 'velocity' etc.
68 """
[710]69 if self._plotter.is_dead:
70 self._plotter = self._newplotter()
[600]71 self._plotter.hold()
[203]72 self._plotter.clear()
[920]73 from asap import scantable
[935]74 if not self._data and not scan:
[1101]75 msg = "Input is not a scantable"
76 if rcParams['verbose']:
77 print msg
78 return
79 raise TypeError(msg)
[920]80 if isinstance(scan, scantable):
[709]81 if self._data is not None:
[920]82 if scan != self._data:
83 self._data = scan
[710]84 # reset
85 self._reset()
[525]86 else:
[920]87 self._data = scan
[710]88 self._reset()
[709]89 # ranges become invalid when unit changes
[935]90 if self._abcunit and self._abcunit != self._data.get_unit():
[709]91 self._minmaxx = None
92 self._minmaxy = None
[920]93 self._abcunit = self._data.get_unit()
[710]94 self._datamask = None
[920]95 self._plot(self._data)
[709]96 if self._minmaxy is not None:
97 self._plotter.set_limits(ylim=self._minmaxy)
[203]98 self._plotter.release()
[1153]99 self._plotter.tidy()
100 self._plotter.show(hardrefresh=False)
[753]101 print_log()
[203]102 return
103
[1153]104
105 # forwards to matplotlib axes
106 def text(self, *args, **kwargs):
107 self._axes_callback("text", *args, **kwargs)
108 text. __doc__ = matplotlib.axes.Axes.text.__doc__
109 def arrow(self, *args, **kwargs):
110 self._axes_callback("arrow", *args, **kwargs)
111 arrow. __doc__ = matplotlib.axes.Axes.arrow.__doc__
112 def axvline(self, *args, **kwargs):
113 self._axes_callback("axvline", *args, **kwargs)
114 axvline. __doc__ = matplotlib.axes.Axes.axvline.__doc__
115 def axhline(self, *args, **kwargs):
116 self._axes_callback("axhline", *args, **kwargs)
117 axhline. __doc__ = matplotlib.axes.Axes.axhline.__doc__
118 def axvspan(self, *args, **kwargs):
119 self._axes_callback("axvspan", *args, **kwargs)
120 # hack to preventy mpl from redrawing the patch
121 # it seem to convert the patch into lines on every draw.
122 # This doesn't happen in a test script???
123 del self._plotter.axes.patches[-1]
124 axvspan. __doc__ = matplotlib.axes.Axes.axvspan.__doc__
125 def axhspan(self, *args, **kwargs):
126 self._axes_callback("ahvspan", *args, **kwargs)
127 # hack to preventy mpl from redrawing the patch
128 # it seem to convert the patch into lines on every draw.
129 # This doesn't happen in a test script???
130 del self._plotter.axes.patches[-1]
131 axhspan. __doc__ = matplotlib.axes.Axes.axhspan.__doc__
132
133 def _axes_callback(self, axesfunc, *args, **kwargs):
134 panel = 0
135 if kwargs.has_key("panel"):
136 panel = kwargs.pop("panel")
137 coords = None
138 if kwargs.has_key("coords"):
139 coords = kwargs.pop("coords")
140 if coords.lower() == 'world':
141 kwargs["transform"] = self._plotter.axes.transData
142 elif coords.lower() == 'relative':
143 kwargs["transform"] = self._plotter.axes.transAxes
144 self._plotter.subplot(panel)
145 self._plotter.axes.set_autoscale_on(False)
146 getattr(self._plotter.axes, axesfunc)(*args, **kwargs)
147 self._plotter.show(False)
148 self._plotter.axes.set_autoscale_on(True)
149 # end matplotlib.axes fowarding functions
150
[226]151 def set_mode(self, stacking=None, panelling=None):
[203]152 """
[377]153 Set the plots look and feel, i.e. what you want to see on the plot.
[203]154 Parameters:
155 stacking: tell the plotter which variable to plot
[1217]156 as line colour overlays (default 'pol')
[203]157 panelling: tell the plotter which variable to plot
158 across multiple panels (default 'scan'
159 Note:
160 Valid modes are:
161 'beam' 'Beam' 'b': Beams
162 'if' 'IF' 'i': IFs
163 'pol' 'Pol' 'p': Polarisations
164 'scan' 'Scan' 's': Scans
165 'time' 'Time' 't': Times
166 """
[753]167 msg = "Invalid mode"
168 if not self.set_panelling(panelling) or \
169 not self.set_stacking(stacking):
170 if rcParams['verbose']:
171 print msg
172 return
173 else:
174 raise TypeError(msg)
[920]175 if self._data: self.plot(self._data)
[203]176 return
177
[554]178 def set_panelling(self, what=None):
179 mode = what
180 if mode is None:
181 mode = rcParams['plotter.panelling']
182 md = self._translate(mode)
[203]183 if md:
[554]184 self._panelling = md
[226]185 self._title = None
[203]186 return True
187 return False
188
[377]189 def set_layout(self,rows=None,cols=None):
190 """
191 Set the multi-panel layout, i.e. how many rows and columns plots
192 are visible.
193 Parameters:
194 rows: The number of rows of plots
195 cols: The number of columns of plots
196 Note:
197 If no argument is given, the potter reverts to its auto-plot
198 behaviour.
199 """
200 self._rows = rows
201 self._cols = cols
[920]202 if self._data: self.plot(self._data)
[377]203 return
204
[709]205 def set_stacking(self, what=None):
[554]206 mode = what
[709]207 if mode is None:
208 mode = rcParams['plotter.stacking']
[554]209 md = self._translate(mode)
[203]210 if md:
211 self._stacking = md
[226]212 self._lmap = None
[203]213 return True
214 return False
215
[525]216 def set_range(self,xstart=None,xend=None,ystart=None,yend=None):
[203]217 """
218 Set the range of interest on the abcissa of the plot
219 Parameters:
[525]220 [x,y]start,[x,y]end: The start and end points of the 'zoom' window
[203]221 Note:
222 These become non-sensical when the unit changes.
223 use plotter.set_range() without parameters to reset
224
225 """
[525]226 if xstart is None and xend is None:
227 self._minmaxx = None
[600]228 else:
229 self._minmaxx = [xstart,xend]
[525]230 if ystart is None and yend is None:
231 self._minmaxy = None
[600]232 else:
[709]233 self._minmaxy = [ystart,yend]
[920]234 if self._data: self.plot(self._data)
[203]235 return
[709]236
[1101]237 def set_legend(self, mp=None, fontsize = None, mode = 0):
[203]238 """
239 Specify a mapping for the legend instead of using the default
240 indices:
241 Parameters:
[1101]242 mp: a list of 'strings'. This should have the same length
243 as the number of elements on the legend and then maps
244 to the indeces in order. It is possible to uses latex
245 math expression. These have to be enclosed in r'',
246 e.g. r'$x^{2}$'
247 fontsize: The font size of the label (default None)
248 mode: where to display the legend
249 Any other value for loc else disables the legend:
[1096]250 0: auto
251 1: upper right
252 2: upper left
253 3: lower left
254 4: lower right
255 5: right
256 6: center left
257 7: center right
258 8: lower center
259 9: upper center
260 10: center
[203]261
262 Example:
[485]263 If the data has two IFs/rest frequencies with index 0 and 1
[203]264 for CO and SiO:
265 plotter.set_stacking('i')
[710]266 plotter.set_legend(['CO','SiO'])
[203]267 plotter.plot()
[710]268 plotter.set_legend([r'$^{12}CO$', r'SiO'])
[203]269 """
270 self._lmap = mp
[1096]271 self._plotter.legend(mode)
[1101]272 if isinstance(fontsize, int):
273 from matplotlib import rc as rcp
274 rcp('legend', fontsize=fontsize)
[1096]275 if self._data:
276 self.plot(self._data)
[226]277 return
278
[1101]279 def set_title(self, title=None, fontsize=None):
[710]280 """
281 Set the title of the plot. If multiple panels are plotted,
282 multiple titles have to be specified.
283 Example:
284 # two panels are visible on the plotter
285 plotter.set_title(["First Panel","Second Panel"])
286 """
[226]287 self._title = title
[1101]288 if isinstance(fontsize, int):
289 from matplotlib import rc as rcp
290 rcp('axes', titlesize=fontsize)
[920]291 if self._data: self.plot(self._data)
[226]292 return
293
[1101]294 def set_ordinate(self, ordinate=None, fontsize=None):
[710]295 """
296 Set the y-axis label of the plot. If multiple panels are plotted,
297 multiple labels have to be specified.
[1021]298 Parameters:
299 ordinate: a list of ordinate labels. None (default) let
300 data determine the labels
[710]301 Example:
302 # two panels are visible on the plotter
303 plotter.set_ordinate(["First Y-Axis","Second Y-Axis"])
304 """
[257]305 self._ordinate = ordinate
[1101]306 if isinstance(fontsize, int):
307 from matplotlib import rc as rcp
308 rcp('axes', labelsize=fontsize)
309 rcp('ytick', labelsize=fontsize)
[920]310 if self._data: self.plot(self._data)
[257]311 return
312
[1101]313 def set_abcissa(self, abcissa=None, fontsize=None):
[710]314 """
315 Set the x-axis label of the plot. If multiple panels are plotted,
316 multiple labels have to be specified.
[1021]317 Parameters:
318 abcissa: a list of abcissa labels. None (default) let
319 data determine the labels
[710]320 Example:
321 # two panels are visible on the plotter
322 plotter.set_ordinate(["First X-Axis","Second X-Axis"])
323 """
[257]324 self._abcissa = abcissa
[1101]325 if isinstance(fontsize, int):
326 from matplotlib import rc as rcp
327 rcp('axes', labelsize=fontsize)
328 rcp('xtick', labelsize=fontsize)
[920]329 if self._data: self.plot(self._data)
[257]330 return
331
[1217]332 def set_colors(self, colmap):
[377]333 """
[1217]334 Set the colours to be used. The plotter will cycle through
335 these colours when lines are overlaid (stacking mode).
[1021]336 Parameters:
[1217]337 colmap: a list of colour names
[710]338 Example:
339 plotter.set_colors("red green blue")
340 # If for example four lines are overlaid e.g I Q U V
341 # 'I' will be 'red', 'Q' will be 'green', U will be 'blue'
342 # and 'V' will be 'red' again.
343 """
[1217]344 if isinstance(colmap,str):
345 colmap = colmap.split()
346 self._plotter.palette(0, colormap=colmap)
[920]347 if self._data: self.plot(self._data)
[710]348
[1217]349 # alias for english speakers
350 set_colours = set_colors
351
[1101]352 def set_histogram(self, hist=True, linewidth=None):
[1021]353 """
354 Enable/Disable histogram-like plotting.
355 Parameters:
356 hist: True (default) or False. The fisrt default
357 is taken from the .asaprc setting
358 plotter.histogram
359 """
[1023]360 self._hist = hist
[1101]361 if isinstance(linewidth, float) or isinstance(linewidth, int):
362 from matplotlib import rc as rcp
363 rcp('lines', linewidth=linewidth)
[1021]364 if self._data: self.plot(self._data)
[1023]365
[1101]366 def set_linestyles(self, linestyles=None, linewidth=None):
[710]367 """
[734]368 Set the linestyles to be used. The plotter will cycle through
369 these linestyles when lines are overlaid (stacking mode) AND
370 only one color has been set.
[710]371 Parameters:
372 linestyles: a list of linestyles to use.
373 'line', 'dashed', 'dotted', 'dashdot',
374 'dashdotdot' and 'dashdashdot' are
375 possible
376
377 Example:
378 plotter.set_colors("black")
379 plotter.set_linestyles("line dashed dotted dashdot")
380 # If for example four lines are overlaid e.g I Q U V
381 # 'I' will be 'solid', 'Q' will be 'dashed',
382 # U will be 'dotted' and 'V' will be 'dashdot'.
383 """
384 if isinstance(linestyles,str):
385 linestyles = linestyles.split()
386 self._plotter.palette(color=0,linestyle=0,linestyles=linestyles)
[1101]387 if isinstance(linewidth, float) or isinstance(linewidth, int):
388 from matplotlib import rc as rcp
389 rcp('lines', linewidth=linewidth)
[920]390 if self._data: self.plot(self._data)
[710]391
[1101]392 def set_font(self, family=None, style=None, weight=None, size=None):
393 """
394 Set font properties.
395 Parameters:
396 family: one of 'sans-serif', 'serif', 'cursive', 'fantasy', 'monospace'
397 style: one of 'normal' (or 'roman'), 'italic' or 'oblique'
398 weight: one of 'normal or 'bold'
399 size: the 'general' font size, individual elements can be adjusted
400 seperately
401 """
402 from matplotlib import rc as rcp
403 if isinstance(family, str):
404 rcp('font', family=family)
405 if isinstance(style, str):
406 rcp('font', style=style)
407 if isinstance(weight, str):
408 rcp('font', weight=weight)
409 if isinstance(size, float) or isinstance(size, int):
410 rcp('font', size=size)
411 if self._data: self.plot(self._data)
412
[1169]413 def plot_lines(self, linecat=None, doppler=0.0, deltachan=10, rotate=0.0,
[1146]414 location=None):
415 """
[1158]416 Plot a line catalog.
417 Parameters:
418 linecat: the linecatalog to plot
[1168]419 doppler: the velocity shift to apply to the frequencies
[1158]420 deltachan: the number of channels to include each side of the
421 line to determine a local maximum/minimum
422 rotate: the rotation for the text label
423 location: the location of the line annotation from the 'top',
424 'bottom' or alternate (None - the default)
[1165]425 Notes:
426 If the spectrum is flagged no line will be drawn in that location.
[1146]427 """
428 if not self._data: return
429 from asap._asap import linecatalog
430 if not isinstance(linecat, linecatalog): return
431 if not self._data.get_unit().endswith("GHz"): return
[1153]432 #self._plotter.hold()
433 from matplotlib.numerix import ma
[1146]434 for j in range(len(self._plotter.subplots)):
435 self._plotter.subplot(j)
436 lims = self._plotter.axes.get_xlim()
[1153]437 for row in range(linecat.nrow()):
[1165]438 restf = linecat.get_frequency(row)/1000.0
439 c = 299792.458
[1174]440 freq = restf*(1.0-doppler/c)
[1146]441 if lims[0] < freq < lims[1]:
442 if location is None:
443 loc = 'bottom'
[1153]444 if row%2: loc='top'
[1146]445 else: loc = location
[1153]446 maxys = []
447 for line in self._plotter.axes.lines:
448 v = line._x
449 asc = v[0] < v[-1]
450
451 idx = None
452 if not asc:
453 if v[len(v)-1] <= freq <= v[0]:
454 i = len(v)-1
455 while i>=0 and v[i] < freq:
456 idx = i
457 i-=1
458 else:
459 if v[0] <= freq <= v[len(v)-1]:
460 i = 0
461 while i<len(v) and v[i] < freq:
462 idx = i
463 i+=1
464 if idx is not None:
465 lower = idx - deltachan
466 upper = idx + deltachan
467 if lower < 0: lower = 0
468 if upper > len(v): upper = len(v)
469 s = slice(lower, upper)
[1167]470 y = line._y[s]
[1165]471 maxy = ma.maximum(y)
472 if isinstance( maxy, float):
473 maxys.append(maxy)
[1164]474 if len(maxys):
475 peak = max(maxys)
[1165]476 if peak > self._plotter.axes.get_ylim()[1]:
477 loc = 'bottom'
[1164]478 else:
479 continue
[1157]480 self._plotter.vline_with_label(freq, peak,
481 linecat.get_name(row),
482 location=loc, rotate=rotate)
[1153]483 # self._plotter.release()
484 self._plotter.show(hardrefresh=False)
[1146]485
[1153]486
[710]487 def save(self, filename=None, orientation=None, dpi=None):
488 """
[377]489 Save the plot to a file. The know formats are 'png', 'ps', 'eps'.
490 Parameters:
491 filename: The name of the output file. This is optional
492 and autodetects the image format from the file
493 suffix. If non filename is specified a file
494 called 'yyyymmdd_hhmmss.png' is created in the
495 current directory.
[709]496 orientation: optional parameter for postscript only (not eps).
497 'landscape', 'portrait' or None (default) are valid.
498 If None is choosen for 'ps' output, the plot is
499 automatically oriented to fill the page.
[710]500 dpi: The dpi of the output non-ps plot
[377]501 """
[709]502 self._plotter.save(filename,orientation,dpi)
[377]503 return
[709]504
[257]505
[920]506 def set_mask(self, mask=None, selection=None):
[525]507 """
[734]508 Set a plotting mask for a specific polarization.
509 This is useful for masking out "noise" Pangle outside a source.
510 Parameters:
[920]511 mask: a mask from scantable.create_mask
512 selection: the spectra to apply the mask to.
[734]513 Example:
[920]514 select = selector()
515 select.setpolstrings("Pangle")
516 plotter.set_mask(mymask, select)
[734]517 """
[710]518 if not self._data:
[920]519 msg = "Can only set mask after a first call to plot()"
[753]520 if rcParams['verbose']:
521 print msg
[762]522 return
[753]523 else:
[762]524 raise RuntimeError(msg)
[920]525 if len(mask):
526 if isinstance(mask, list) or isinstance(mask, tuple):
527 self._usermask = array(mask)
[710]528 else:
[920]529 self._usermask = mask
530 if mask is None and selection is None:
531 self._usermask = []
532 self._maskselection = None
533 if isinstance(selection, selector):
[947]534 self._maskselection = {'b': selection.get_beams(),
535 's': selection.get_scans(),
536 'i': selection.get_ifs(),
537 'p': selection.get_pols(),
[920]538 't': [] }
[710]539 else:
[920]540 self._maskselection = None
541 self.plot(self._data)
[710]542
[709]543 def _slice_indeces(self, data):
544 mn = self._minmaxx[0]
545 mx = self._minmaxx[1]
546 asc = data[0] < data[-1]
547 start=0
548 end = len(data)-1
549 inc = 1
550 if not asc:
551 start = len(data)-1
552 end = 0
553 inc = -1
554 # find min index
[1101]555 while start > 0 and data[start] < mn:
[709]556 start+= inc
557 # find max index
[1101]558 while end > 0 and data[end] > mx:
[709]559 end-=inc
[1101]560 if end > 0: end +=1
[709]561 if start > end:
562 return end,start
563 return start,end
564
[710]565 def _reset(self):
[920]566 self._usermask = []
[710]567 self._usermaskspectra = None
[920]568 self.set_selection(None, False)
569
570 def _plot(self, scan):
[947]571 savesel = scan.get_selection()
572 sel = savesel + self._selection
573 d0 = {'s': 'SCANNO', 'b': 'BEAMNO', 'i':'IFNO',
574 'p': 'POLNO', 'c': 'CYCLENO', 't' : 'TIME' }
575 order = [d0[self._panelling],d0[self._stacking]]
576 sel.set_order(order)
577 scan.set_selection(sel)
[920]578 d = {'b': scan.getbeam, 's': scan.getscan,
579 'i': scan.getif, 'p': scan.getpol, 't': scan._gettime }
580
[1148]581 polmodes = dict(zip(self._selection.get_pols(),
582 self._selection.get_poltypes()))
583 # this returns either a tuple of numbers or a length (ncycles)
584 # convert this into lengths
585 n0,nstack0 = self._get_selected_n(scan)
586 if isinstance(n0, int): n = n0
[1175]587 else: n = len(n0)
[1148]588 if isinstance(nstack0, int): nstack = nstack0
[1175]589 else: nstack = len(nstack0)
[998]590 maxpanel, maxstack = 16,8
[920]591 if n > maxpanel or nstack > maxstack:
592 from asap import asaplog
[1148]593 maxn = 0
594 if nstack > maxstack: maxn = maxstack
595 if n > maxpanel: maxn = maxpanel
[920]596 msg ="Scan to be plotted contains more than %d selections.\n" \
[1148]597 "Selecting first %d selections..." % (maxn, maxn)
[920]598 asaplog.push(msg)
599 print_log()
600 n = min(n,maxpanel)
[998]601 nstack = min(nstack,maxstack)
[920]602 if n > 1:
603 ganged = rcParams['plotter.ganged']
604 if self._rows and self._cols:
605 n = min(n,self._rows*self._cols)
606 self._plotter.set_panels(rows=self._rows,cols=self._cols,
607 nplots=n,ganged=ganged)
608 else:
609 self._plotter.set_panels(rows=n,cols=0,nplots=n,ganged=ganged)
610 else:
611 self._plotter.set_panels()
612 r=0
613 nr = scan.nrow()
614 a0,b0 = -1,-1
615 allxlim = []
[1018]616 allylim = []
[920]617 newpanel=True
618 panelcount,stackcount = 0,0
[1002]619 while r < nr:
[920]620 a = d[self._panelling](r)
621 b = d[self._stacking](r)
622 if a > a0 and panelcount < n:
623 if n > 1:
624 self._plotter.subplot(panelcount)
625 self._plotter.palette(0)
626 #title
627 xlab = self._abcissa and self._abcissa[panelcount] \
628 or scan._getabcissalabel()
629 ylab = self._ordinate and self._ordinate[panelcount] \
630 or scan._get_ordinate_label()
631 self._plotter.set_axes('xlabel',xlab)
632 self._plotter.set_axes('ylabel',ylab)
633 lbl = self._get_label(scan, r, self._panelling, self._title)
634 if isinstance(lbl, list) or isinstance(lbl, tuple):
635 if 0 <= panelcount < len(lbl):
636 lbl = lbl[panelcount]
637 else:
638 # get default label
639 lbl = self._get_label(scan, r, self._panelling, None)
640 self._plotter.set_axes('title',lbl)
641 newpanel = True
642 stackcount =0
643 panelcount += 1
644 if (b > b0 or newpanel) and stackcount < nstack:
645 y = []
646 if len(polmodes):
647 y = scan._getspectrum(r, polmodes[scan.getpol(r)])
648 else:
649 y = scan._getspectrum(r)
650 m = scan._getmask(r)
[1146]651 from matplotlib.numerix import logical_not, logical_and
[920]652 if self._maskselection and len(self._usermask) == len(m):
653 if d[self._stacking](r) in self._maskselection[self._stacking]:
654 m = logical_and(m, self._usermask)
655 x = scan._getabcissa(r)
[1146]656 from matplotlib.numerix import ma, array
[1116]657 y = ma.masked_array(y,mask=logical_not(array(m,copy=False)))
[920]658 if self._minmaxx is not None:
659 s,e = self._slice_indeces(x)
660 x = x[s:e]
661 y = y[s:e]
[1096]662 if len(x) > 1024 and rcParams['plotter.decimate']:
663 fac = len(x)/1024
[920]664 x = x[::fac]
665 y = y[::fac]
666 llbl = self._get_label(scan, r, self._stacking, self._lmap)
667 if isinstance(llbl, list) or isinstance(llbl, tuple):
668 if 0 <= stackcount < len(llbl):
669 # use user label
670 llbl = llbl[stackcount]
671 else:
672 # get default label
673 llbl = self._get_label(scan, r, self._stacking, None)
674 self._plotter.set_line(label=llbl)
[1023]675 plotit = self._plotter.plot
676 if self._hist: plotit = self._plotter.hist
[1146]677 if len(x) > 0:
678 plotit(x,y)
679 xlim= self._minmaxx or [min(x),max(x)]
680 allxlim += xlim
681 ylim= self._minmaxy or [ma.minimum(y),ma.maximum(y)]
682 allylim += ylim
[920]683 stackcount += 1
684 # last in colour stack -> autoscale x
685 if stackcount == nstack:
686 allxlim.sort()
687 self._plotter.axes.set_xlim([allxlim[0],allxlim[-1]])
688 # clear
689 allxlim =[]
690
691 newpanel = False
692 a0=a
693 b0=b
694 # ignore following rows
695 if (panelcount == n) and (stackcount == nstack):
[1018]696 # last panel -> autoscale y if ganged
697 if rcParams['plotter.ganged']:
698 allylim.sort()
699 self._plotter.set_limits(ylim=[allylim[0],allylim[-1]])
[998]700 break
[920]701 r+=1 # next row
[947]702 #reset the selector to the scantable's original
703 scan.set_selection(savesel)
[920]704
705 def set_selection(self, selection=None, refresh=True):
[947]706 self._selection = isinstance(selection,selector) and selection or selector()
[920]707 d0 = {'s': 'SCANNO', 'b': 'BEAMNO', 'i':'IFNO',
708 'p': 'POLNO', 'c': 'CYCLENO', 't' : 'TIME' }
709 order = [d0[self._panelling],d0[self._stacking]]
[947]710 self._selection.set_order(order)
[920]711 if self._data and refresh: self.plot(self._data)
712
713 def _get_selected_n(self, scan):
[1148]714 d1 = {'b': scan.getbeamnos, 's': scan.getscannos,
715 'i': scan.getifnos, 'p': scan.getpolnos, 't': scan.ncycle }
716 d2 = { 'b': self._selection.get_beams(),
717 's': self._selection.get_scans(),
718 'i': self._selection.get_ifs(),
719 'p': self._selection.get_pols(),
720 't': self._selection.get_cycles() }
[920]721 n = d2[self._panelling] or d1[self._panelling]()
722 nstack = d2[self._stacking] or d1[self._stacking]()
723 return n,nstack
724
725 def _get_label(self, scan, row, mode, userlabel=None):
[1153]726 if isinstance(userlabel, list) and len(userlabel) == 0:
727 userlabel = " "
[947]728 pms = dict(zip(self._selection.get_pols(),self._selection.get_poltypes()))
[920]729 if len(pms):
730 poleval = scan._getpollabel(scan.getpol(row),pms[scan.getpol(row)])
731 else:
732 poleval = scan._getpollabel(scan.getpol(row),scan.poltype())
733 d = {'b': "Beam "+str(scan.getbeam(row)),
734 's': scan._getsourcename(row),
735 'i': "IF"+str(scan.getif(row)),
[964]736 'p': poleval,
[1175]737 't': str(scan.get_time(row)) }
[920]738 return userlabel or d[mode]
[1153]739
Note: See TracBrowser for help on using the repository browser.