source: trunk/python/asapplotter.py@ 1192

Last change on this file since 1192 was 1175, checked in by mar637, 18 years ago

various changes to support the pylab plotter 'xyplotter'

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