Changeset 2700
- Timestamp:
- 12/17/12 19:38:05 (12 years ago)
- Location:
- trunk/python
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/python/asaplotbase.py
r2699 r2700 88 88 'motion_notify':None} 89 89 90 def _alive(self): 91 # Return True if the GUI alives. 92 if (not self.is_dead) and \ 93 self.figmgr and hasattr(self.figmgr, "num"): 94 figid = self.figmgr.num 95 # Make sure figid=0 is what asapplotter expects. 96 # It might be already destroied/overridden by matplotlib 97 # commands or other methods using asaplot. 98 return _pylab_helpers.Gcf.has_fignum(figid) and \ 99 (self.figmgr == _pylab_helpers.Gcf.get_fig_manager(figid)) 100 return False 101 102 103 ### Delete artists ### 90 104 def clear(self): 91 105 """ … … 101 115 self.lines = [] 102 116 self.subplots[self.i]['lines'] = self.lines 117 118 def delete(self, numbers=None): 119 """ 120 Delete the 0-relative line number, default is to delete the last. 121 The remaining lines are NOT renumbered. 122 """ 123 124 if numbers is None: numbers = [len(self.lines)-1] 125 126 if not hasattr(numbers, '__iter__'): 127 numbers = [numbers] 128 129 for number in numbers: 130 if 0 <= number < len(self.lines): 131 if self.lines[number] is not None: 132 for line in self.lines[number]: 133 line.set_linestyle('None') 134 self.lines[number] = None 135 self.show() 136 137 138 ### Set plot parameters ### 139 def hold(self, hold=True): 140 """ 141 Buffer graphics until subsequently released. 142 """ 143 self.buffering = hold 103 144 104 145 def palette(self, color, colormap=None, linestyle=0, linestyles=None): … … 124 165 self.linestyle = linestyle 125 166 126 def delete(self, numbers=None):127 """128 Delete the 0-relative line number, default is to delete the last.129 The remaining lines are NOT renumbered.130 """131 132 if numbers is None: numbers = [len(self.lines)-1]133 134 if not hasattr(numbers, '__iter__'):135 numbers = [numbers]136 137 for number in numbers:138 if 0 <= number < len(self.lines):139 if self.lines[number] is not None:140 for line in self.lines[number]:141 line.set_linestyle('None')142 self.lines[number] = None143 self.show()144 145 def get_line(self):146 """147 Get the current default line attributes.148 """149 return self.attributes150 151 152 def hist(self, x=None, y=None, fmt=None, add=None):153 """154 Plot a histogram. N.B. the x values refer to the start of the155 histogram bin.156 157 fmt is the line style as in plot().158 """159 from numpy import array160 from numpy.ma import MaskedArray161 if x is None:162 if y is None: return163 x = range(len(y))164 165 if len(x) != len(y):166 return167 l2 = 2*len(x)168 x2 = range(l2)169 y2 = range(12)170 y2 = range(l2)171 m2 = range(l2)172 ymsk = None173 ydat = None174 if hasattr(y, "raw_mask"):175 # numpy < 1.1176 ymsk = y.raw_mask()177 ydat = y.raw_data()178 else:179 ymsk = y.mask180 ydat = y.data181 for i in range(l2):182 x2[i] = x[i/2]183 m2[i] = ymsk[i/2]184 185 y2[0] = 0.0186 for i in range(1,l2):187 y2[i] = ydat[(i-1)/2]188 189 self.plot(x2, MaskedArray(y2,mask=m2,copy=0), fmt, add)190 191 192 def hold(self, hold=True):193 """194 Buffer graphics until subsequently released.195 """196 self.buffering = hold197 198 199 167 def legend(self, loc=None): 200 168 """ … … 220 188 self.loc = None 221 189 #self.show() 222 223 224 def plot(self, x=None, y=None, fmt=None, add=None):225 """226 Plot the next line in the current frame using the current line227 attributes. The ASAPlot graphics window will be mapped and raised.228 229 The argument list works a bit like the matlab plot() function.230 """231 if x is None:232 if y is None: return233 x = range(len(y))234 235 elif y is None:236 y = x237 x = range(len(y))238 if fmt is None:239 line = self.axes.plot(x, y)240 else:241 line = self.axes.plot(x, y, fmt)242 # add a picker to lines for spectral value mode.243 # matplotlib.axes.plot returns a list of line object (1 element)244 line[0].set_picker(5.0)245 246 # Add to an existing line?247 i = None248 if add is None or len(self.lines) < add < 0:249 # Don't add.250 self.lines.append(line)251 i = len(self.lines) - 1252 else:253 if add == 0: add = len(self.lines)254 i = add - 1255 self.lines[i].extend(line)256 257 # Set/reset attributes for the line.258 gotcolour = False259 for k, v in self.attributes.iteritems():260 if k == 'color': gotcolour = True261 for segment in self.lines[i]:262 getattr(segment, "set_%s"%k)(v)263 264 if not gotcolour and len(self.colormap):265 for segment in self.lines[i]:266 getattr(segment, "set_color")(self.colormap[self.color])267 if len(self.colormap) == 1:268 getattr(segment, "set_dashes")(self.linestyles[self.linestyle])269 270 self.color += 1271 if self.color >= len(self.colormap):272 self.color = 0273 274 if len(self.colormap) == 1:275 self.linestyle += 1276 if self.linestyle >= len(self.linestyles):277 self.linestyle = 0278 279 self.show()280 281 282 def position(self):283 """284 Use the mouse to get a position from a graph.285 """286 287 def position_disable(event):288 self.register('button_press', None)289 print '%.4f, %.4f' % (event.xdata, event.ydata)290 291 print 'Press any mouse button...'292 self.register('button_press', position_disable)293 294 295 def get_region(self):296 pos = []297 print "Please select the bottom/left point"298 pos.append(self.figure.ginput(n=1, show_clicks=False)[0])299 print "Please select the top/right point"300 pos.append(self.figure.ginput(n=1, show_clicks=False)[0])301 return pos302 303 def get_point(self):304 print "Please select the point"305 pt = self.figure.ginput(n=1, show_clicks=False)306 if pt:307 return pt[0]308 else:309 return None310 311 def region(self):312 """313 Use the mouse to get a rectangular region from a plot.314 315 The return value is [x0, y0, x1, y1] in world coordinates.316 """317 318 def region_start(event):319 self.rect = {'x': event.x, 'y': event.y,320 'world': [event.xdata, event.ydata,321 event.xdata, event.ydata]}322 self.register('button_press', None)323 self.register('motion_notify', region_draw)324 self.register('button_release', region_disable)325 326 def region_draw(event):327 self.figmgr.toolbar.draw_rubberband(event, event.x, event.y,328 self.rect['x'], self.rect['y'])329 330 def region_disable(event):331 self.register('motion_notify', None)332 self.register('button_release', None)333 334 self.rect['world'][2:4] = [event.xdata, event.ydata]335 print '(%.2f, %.2f) (%.2f, %.2f)' % (self.rect['world'][0],336 self.rect['world'][1], self.rect['world'][2],337 self.rect['world'][3])338 self.figmgr.toolbar.release(event)339 340 self.register('button_press', region_start)341 342 # This has to be modified to block and return the result (currently343 # printed by region_disable) when that becomes possible in matplotlib.344 345 return [0.0, 0.0, 0.0, 0.0]346 347 348 def register(self, type=None, func=None):349 """350 Register, reregister, or deregister events of type 'button_press',351 'button_release', or 'motion_notify'.352 353 The specified callback function should have the following signature:354 355 def func(event)356 357 where event is an MplEvent instance containing the following data:358 359 name # Event name.360 canvas # FigureCanvas instance generating the event.361 x = None # x position - pixels from left of canvas.362 y = None # y position - pixels from bottom of canvas.363 button = None # Button pressed: None, 1, 2, 3.364 key = None # Key pressed: None, chr(range(255)), shift,365 win, or control366 inaxes = None # Axes instance if cursor within axes.367 xdata = None # x world coordinate.368 ydata = None # y world coordinate.369 370 For example:371 372 def mouse_move(event):373 print event.xdata, event.ydata374 375 a = asaplot()376 a.register('motion_notify', mouse_move)377 378 If func is None, the event is deregistered.379 380 Note that in TkAgg keyboard button presses don't generate an event.381 """382 383 if not self.events.has_key(type): return384 385 if func is None:386 if self.events[type] is not None:387 # It's not clear that this does anything.388 self.canvas.mpl_disconnect(self.events[type])389 self.events[type] = None390 391 # It seems to be necessary to return events to the toolbar. <-- Not ture. 2010.Jul.14.kana.392 #if type == 'motion_notify':393 # self.canvas.mpl_connect(type + '_event',394 # self.figmgr.toolbar.mouse_move)395 #elif type == 'button_press':396 # self.canvas.mpl_connect(type + '_event',397 # self.figmgr.toolbar.press)398 #elif type == 'button_release':399 # self.canvas.mpl_connect(type + '_event',400 # self.figmgr.toolbar.release)401 402 else:403 self.events[type] = self.canvas.mpl_connect(type + '_event', func)404 405 406 def release(self):407 """408 Release buffered graphics.409 """410 self.buffering = False411 self.show()412 413 414 def save(self, fname=None, orientation=None, dpi=None, papertype=None):415 """416 Save the plot to a file.417 418 fname is the name of the output file. The image format is determined419 from the file suffix; 'png', 'ps', and 'eps' are recognized. If no420 file name is specified 'yyyymmdd_hhmmss.png' is created in the current421 directory.422 """423 from asap import rcParams424 if papertype is None:425 papertype = rcParams['plotter.papertype']426 if fname is None:427 from datetime import datetime428 dstr = datetime.now().strftime('%Y%m%d_%H%M%S')429 fname = 'asap'+dstr+'.png'430 431 d = ['png','.ps','eps', 'svg']432 433 from os.path import expandvars434 fname = expandvars(fname)435 436 if fname[-3:].lower() in d:437 try:438 if fname[-3:].lower() == ".ps":439 from matplotlib import __version__ as mv440 w = self.figure.get_figwidth()441 h = self.figure.get_figheight()442 443 if orientation is None:444 # oriented445 if w > h:446 orientation = 'landscape'447 else:448 orientation = 'portrait'449 from matplotlib.backends.backend_ps import papersize450 pw,ph = papersize[papertype.lower()]451 ds = None452 if orientation == 'landscape':453 ds = min(ph/w, pw/h)454 else:455 ds = min(pw/w, ph/h)456 ow = ds * w457 oh = ds * h458 self.figure.set_size_inches((ow, oh))459 self.figure.savefig(fname, orientation=orientation,460 papertype=papertype.lower())461 self.figure.set_size_inches((w, h))462 print 'Written file %s' % (fname)463 else:464 if dpi is None:465 dpi =150466 self.figure.savefig(fname,dpi=dpi)467 print 'Written file %s' % (fname)468 except IOError, msg:469 #print 'Failed to save %s: Error msg was\n\n%s' % (fname, err)470 asaplog.post()471 asaplog.push('Failed to save %s: Error msg was\n\n%s' % (fname, str(msg)))472 asaplog.post( 'ERROR' )473 return474 else:475 #print "Invalid image type. Valid types are:"476 #print "'ps', 'eps', 'png'"477 asaplog.push( "Invalid image type. Valid types are:" )478 asaplog.push( "'ps', 'eps', 'png', 'svg'" )479 asaplog.post('WARN')480 481 482 def set_axes(self, what=None, *args, **kwargs):483 """484 Set attributes for the axes by calling the relevant Axes.set_*()485 method. Colour translation is done as described in the doctext486 for palette().487 """488 489 if what is None: return490 if what[-6:] == 'colour': what = what[:-6] + 'color'491 492 key = "colour"493 if kwargs.has_key(key):494 val = kwargs.pop(key)495 kwargs["color"] = val496 497 getattr(self.axes, "set_%s"%what)(*args, **kwargs)498 499 self.show(hardrefresh=False)500 501 502 def set_figure(self, what=None, *args, **kwargs):503 """504 Set attributes for the figure by calling the relevant Figure.set_*()505 method. Colour translation is done as described in the doctext506 for palette().507 """508 509 if what is None: return510 if what[-6:] == 'colour': what = what[:-6] + 'color'511 #if what[-5:] == 'color' and len(args):512 # args = (get_colour(args[0]),)513 514 newargs = {}515 for k, v in kwargs.iteritems():516 k = k.lower()517 if k == 'colour': k = 'color'518 newargs[k] = v519 520 getattr(self.figure, "set_%s"%what)(*args, **newargs)521 self.show(hardrefresh=False)522 523 524 def set_limits(self, xlim=None, ylim=None):525 """526 Set x-, and y-limits for each subplot.527 528 xlim = [xmin, xmax] as in axes.set_xlim().529 ylim = [ymin, ymax] as in axes.set_ylim().530 """531 for s in self.subplots:532 self.axes = s['axes']533 self.lines = s['lines']534 oldxlim = list(self.axes.get_xlim())535 oldylim = list(self.axes.get_ylim())536 if xlim is not None:537 for i in range(len(xlim)):538 if xlim[i] is not None:539 oldxlim[i] = xlim[i]540 if ylim is not None:541 for i in range(len(ylim)):542 if ylim[i] is not None:543 oldylim[i] = ylim[i]544 self.axes.set_xlim(oldxlim)545 self.axes.set_ylim(oldylim)546 return547 548 549 def set_line(self, number=None, **kwargs):550 """551 Set attributes for the specified line, or else the next line(s)552 to be plotted.553 554 number is the 0-relative number of a line that has already been555 plotted. If no such line exists, attributes are recorded and used556 for the next line(s) to be plotted.557 558 Keyword arguments specify Line2D attributes, e.g. color='r'. Do559 560 import matplotlib561 help(matplotlib.lines)562 563 The set_* methods of class Line2D define the attribute names and564 values. For non-US usage, 'colour' is recognized as synonymous with565 'color'.566 567 Set the value to None to delete an attribute.568 569 Colour translation is done as described in the doctext for palette().570 """571 572 redraw = False573 for k, v in kwargs.iteritems():574 k = k.lower()575 if k == 'colour': k = 'color'576 577 if 0 <= number < len(self.lines):578 if self.lines[number] is not None:579 for line in self.lines[number]:580 getattr(line, "set_%s"%k)(v)581 redraw = True582 else:583 if v is None:584 del self.attributes[k]585 else:586 self.attributes[k] = v587 588 if redraw: self.show(hardrefresh=False)589 590 190 591 191 #def set_panels(self, rows=1, cols=0, n=-1, nplots=-1, ganged=True): … … 700 300 del rows,cols,n,nplots,margin,ganged,i 701 301 302 def subplot(self, i=None, inc=None): 303 """ 304 Set the subplot to the 0-relative panel number as defined by one or 305 more invokations of set_panels(). 306 """ 307 l = len(self.subplots) 308 if l: 309 if i is not None: 310 self.i = i 311 312 if inc is not None: 313 self.i += inc 314 315 self.i %= l 316 self.axes = self.subplots[self.i]['axes'] 317 self.lines = self.subplots[self.i]['lines'] 318 319 def set_axes(self, what=None, *args, **kwargs): 320 """ 321 Set attributes for the axes by calling the relevant Axes.set_*() 322 method. Colour translation is done as described in the doctext 323 for palette(). 324 """ 325 326 if what is None: return 327 if what[-6:] == 'colour': what = what[:-6] + 'color' 328 329 key = "colour" 330 if kwargs.has_key(key): 331 val = kwargs.pop(key) 332 kwargs["color"] = val 333 334 getattr(self.axes, "set_%s"%what)(*args, **kwargs) 335 336 self.show(hardrefresh=False) 337 338 339 def set_figure(self, what=None, *args, **kwargs): 340 """ 341 Set attributes for the figure by calling the relevant Figure.set_*() 342 method. Colour translation is done as described in the doctext 343 for palette(). 344 """ 345 346 if what is None: return 347 if what[-6:] == 'colour': what = what[:-6] + 'color' 348 #if what[-5:] == 'color' and len(args): 349 # args = (get_colour(args[0]),) 350 351 newargs = {} 352 for k, v in kwargs.iteritems(): 353 k = k.lower() 354 if k == 'colour': k = 'color' 355 newargs[k] = v 356 357 getattr(self.figure, "set_%s"%what)(*args, **newargs) 358 self.show(hardrefresh=False) 359 360 361 def set_limits(self, xlim=None, ylim=None): 362 """ 363 Set x-, and y-limits for each subplot. 364 365 xlim = [xmin, xmax] as in axes.set_xlim(). 366 ylim = [ymin, ymax] as in axes.set_ylim(). 367 """ 368 for s in self.subplots: 369 self.axes = s['axes'] 370 self.lines = s['lines'] 371 oldxlim = list(self.axes.get_xlim()) 372 oldylim = list(self.axes.get_ylim()) 373 if xlim is not None: 374 for i in range(len(xlim)): 375 if xlim[i] is not None: 376 oldxlim[i] = xlim[i] 377 if ylim is not None: 378 for i in range(len(ylim)): 379 if ylim[i] is not None: 380 oldylim[i] = ylim[i] 381 self.axes.set_xlim(oldxlim) 382 self.axes.set_ylim(oldylim) 383 return 384 385 386 def set_line(self, number=None, **kwargs): 387 """ 388 Set attributes for the specified line, or else the next line(s) 389 to be plotted. 390 391 number is the 0-relative number of a line that has already been 392 plotted. If no such line exists, attributes are recorded and used 393 for the next line(s) to be plotted. 394 395 Keyword arguments specify Line2D attributes, e.g. color='r'. Do 396 397 import matplotlib 398 help(matplotlib.lines) 399 400 The set_* methods of class Line2D define the attribute names and 401 values. For non-US usage, 'colour' is recognized as synonymous with 402 'color'. 403 404 Set the value to None to delete an attribute. 405 406 Colour translation is done as described in the doctext for palette(). 407 """ 408 409 redraw = False 410 for k, v in kwargs.iteritems(): 411 k = k.lower() 412 if k == 'colour': k = 'color' 413 414 if 0 <= number < len(self.lines): 415 if self.lines[number] is not None: 416 for line in self.lines[number]: 417 getattr(line, "set_%s"%k)(v) 418 redraw = True 419 else: 420 if v is None: 421 del self.attributes[k] 422 else: 423 self.attributes[k] = v 424 425 if redraw: self.show(hardrefresh=False) 426 427 428 def get_line(self): 429 """ 430 Get the current default line attributes. 431 """ 432 return self.attributes 433 434 435 ### Actual plot methods ### 436 def hist(self, x=None, y=None, fmt=None, add=None): 437 """ 438 Plot a histogram. N.B. the x values refer to the start of the 439 histogram bin. 440 441 fmt is the line style as in plot(). 442 """ 443 from numpy import array 444 from numpy.ma import MaskedArray 445 if x is None: 446 if y is None: return 447 x = range(len(y)) 448 449 if len(x) != len(y): 450 return 451 l2 = 2*len(x) 452 x2 = range(l2) 453 y2 = range(12) 454 y2 = range(l2) 455 m2 = range(l2) 456 ymsk = None 457 ydat = None 458 if hasattr(y, "raw_mask"): 459 # numpy < 1.1 460 ymsk = y.raw_mask() 461 ydat = y.raw_data() 462 else: 463 ymsk = y.mask 464 ydat = y.data 465 for i in range(l2): 466 x2[i] = x[i/2] 467 m2[i] = ymsk[i/2] 468 469 y2[0] = 0.0 470 for i in range(1,l2): 471 y2[i] = ydat[(i-1)/2] 472 473 self.plot(x2, MaskedArray(y2,mask=m2,copy=0), fmt, add) 474 475 476 def plot(self, x=None, y=None, fmt=None, add=None): 477 """ 478 Plot the next line in the current frame using the current line 479 attributes. The ASAPlot graphics window will be mapped and raised. 480 481 The argument list works a bit like the matlab plot() function. 482 """ 483 if x is None: 484 if y is None: return 485 x = range(len(y)) 486 487 elif y is None: 488 y = x 489 x = range(len(y)) 490 if fmt is None: 491 line = self.axes.plot(x, y) 492 else: 493 line = self.axes.plot(x, y, fmt) 494 # add a picker to lines for spectral value mode. 495 # matplotlib.axes.plot returns a list of line object (1 element) 496 line[0].set_picker(5.0) 497 498 # Add to an existing line? 499 i = None 500 if add is None or len(self.lines) < add < 0: 501 # Don't add. 502 self.lines.append(line) 503 i = len(self.lines) - 1 504 else: 505 if add == 0: add = len(self.lines) 506 i = add - 1 507 self.lines[i].extend(line) 508 509 # Set/reset attributes for the line. 510 gotcolour = False 511 for k, v in self.attributes.iteritems(): 512 if k == 'color': gotcolour = True 513 for segment in self.lines[i]: 514 getattr(segment, "set_%s"%k)(v) 515 516 if not gotcolour and len(self.colormap): 517 for segment in self.lines[i]: 518 getattr(segment, "set_color")(self.colormap[self.color]) 519 if len(self.colormap) == 1: 520 getattr(segment, "set_dashes")(self.linestyles[self.linestyle]) 521 522 self.color += 1 523 if self.color >= len(self.colormap): 524 self.color = 0 525 526 if len(self.colormap) == 1: 527 self.linestyle += 1 528 if self.linestyle >= len(self.linestyles): 529 self.linestyle = 0 530 531 self.show() 532 702 533 703 534 def tidy(self): … … 731 562 732 563 733 def show(self, hardrefresh=True):734 """735 Show graphics dependent on the current buffering state.736 """737 if not hardrefresh: return738 if not self.buffering:739 if self.loc is not None:740 for sp in self.subplots:741 lines = []742 labels = []743 i = 0744 for line in sp['lines']:745 i += 1746 if line is not None:747 lines.append(line[0])748 lbl = line[0].get_label()749 if lbl == '':750 lbl = str(i)751 labels.append(lbl)752 753 if len(lines):754 fp = FP(size=rcParams['legend.fontsize'])755 #fsz = fp.get_size_in_points() - len(lines)756 fsz = fp.get_size_in_points() - max(len(lines),self.cols)757 #fp.set_size(max(fsz,6))758 fp.set_size(max(fsz,8))759 sp['axes'].legend(tuple(lines), tuple(labels),760 self.loc, prop=fp)761 #else:762 # sp['axes'].legend((' '))763 764 from matplotlib.artist import setp765 fpx = FP(size=rcParams['xtick.labelsize'])766 xts = fpx.get_size_in_points()- (self.cols)/2767 fpy = FP(size=rcParams['ytick.labelsize'])768 yts = fpy.get_size_in_points() - (self.rows)/2769 fpa = FP(size=rcParams['axes.labelsize'])770 fpat = FP(size=rcParams['axes.titlesize'])771 axsize = fpa.get_size_in_points()772 tsize = fpat.get_size_in_points()-(self.cols)/2773 for sp in self.subplots:774 ax = sp['axes']775 ax.title.set_size(tsize)776 setp(ax.get_xticklabels(), fontsize=xts)777 setp(ax.get_yticklabels(), fontsize=yts)778 off = 0779 if self.cols > 1: off = self.cols780 ax.xaxis.label.set_size(axsize-off)781 off = 0782 if self.rows > 1: off = self.rows783 ax.yaxis.label.set_size(axsize-off)784 785 def subplot(self, i=None, inc=None):786 """787 Set the subplot to the 0-relative panel number as defined by one or788 more invokations of set_panels().789 """790 l = len(self.subplots)791 if l:792 if i is not None:793 self.i = i794 795 if inc is not None:796 self.i += inc797 798 self.i %= l799 self.axes = self.subplots[self.i]['axes']800 self.lines = self.subplots[self.i]['lines']801 802 564 def text(self, *args, **kwargs): 803 565 """ … … 811 573 """ 812 574 Plot a vertical line with label. 813 It takes "world"values fo x and y.575 It takes 'world' values fo x and y. 814 576 """ 815 577 ax = self.axes … … 855 617 self.axes.set_autoscale_on(True) 856 618 857 def _alive(self): 858 # Return True if the GUI alives. 859 if (not self.is_dead) and \ 860 self.figmgr and hasattr(self.figmgr, "num"): 861 figid = self.figmgr.num 862 # Make sure figid=0 is what asapplotter expects. 863 # It might be already destroied/overridden by matplotlib 864 # commands or other methods using asaplot. 865 return _pylab_helpers.Gcf.has_fignum(figid) and \ 866 (self.figmgr == _pylab_helpers.Gcf.get_fig_manager(figid)) 867 return False 619 def release(self): 620 """ 621 Release buffered graphics. 622 """ 623 self.buffering = False 624 self.show() 625 626 627 def show(self, hardrefresh=True): 628 """ 629 Show graphics dependent on the current buffering state. 630 """ 631 if not hardrefresh: return 632 if not self.buffering: 633 if self.loc is not None: 634 for sp in self.subplots: 635 lines = [] 636 labels = [] 637 i = 0 638 for line in sp['lines']: 639 i += 1 640 if line is not None: 641 lines.append(line[0]) 642 lbl = line[0].get_label() 643 if lbl == '': 644 lbl = str(i) 645 labels.append(lbl) 646 647 if len(lines): 648 fp = FP(size=rcParams['legend.fontsize']) 649 #fsz = fp.get_size_in_points() - len(lines) 650 fsz = fp.get_size_in_points() - max(len(lines),self.cols) 651 #fp.set_size(max(fsz,6)) 652 fp.set_size(max(fsz,8)) 653 sp['axes'].legend(tuple(lines), tuple(labels), 654 self.loc, prop=fp) 655 #else: 656 # sp['axes'].legend((' ')) 657 658 from matplotlib.artist import setp 659 fpx = FP(size=rcParams['xtick.labelsize']) 660 xts = fpx.get_size_in_points()- (self.cols)/2 661 fpy = FP(size=rcParams['ytick.labelsize']) 662 yts = fpy.get_size_in_points() - (self.rows)/2 663 fpa = FP(size=rcParams['axes.labelsize']) 664 fpat = FP(size=rcParams['axes.titlesize']) 665 axsize = fpa.get_size_in_points() 666 tsize = fpat.get_size_in_points()-(self.cols)/2 667 for sp in self.subplots: 668 ax = sp['axes'] 669 ax.title.set_size(tsize) 670 setp(ax.get_xticklabels(), fontsize=xts) 671 setp(ax.get_yticklabels(), fontsize=yts) 672 off = 0 673 if self.cols > 1: off = self.cols 674 ax.xaxis.label.set_size(axsize-off) 675 off = 0 676 if self.rows > 1: off = self.rows 677 ax.yaxis.label.set_size(axsize-off) 678 679 def save(self, fname=None, orientation=None, dpi=None, papertype=None): 680 """ 681 Save the plot to a file. 682 683 fname is the name of the output file. The image format is determined 684 from the file suffix; 'png', 'ps', and 'eps' are recognized. If no 685 file name is specified 'yyyymmdd_hhmmss.png' is created in the current 686 directory. 687 """ 688 from asap import rcParams 689 if papertype is None: 690 papertype = rcParams['plotter.papertype'] 691 if fname is None: 692 from datetime import datetime 693 dstr = datetime.now().strftime('%Y%m%d_%H%M%S') 694 fname = 'asap'+dstr+'.png' 695 696 d = ['png','.ps','eps', 'svg'] 697 698 from os.path import expandvars 699 fname = expandvars(fname) 700 701 if fname[-3:].lower() in d: 702 try: 703 if fname[-3:].lower() == ".ps": 704 from matplotlib import __version__ as mv 705 w = self.figure.get_figwidth() 706 h = self.figure.get_figheight() 707 708 if orientation is None: 709 # oriented 710 if w > h: 711 orientation = 'landscape' 712 else: 713 orientation = 'portrait' 714 from matplotlib.backends.backend_ps import papersize 715 pw,ph = papersize[papertype.lower()] 716 ds = None 717 if orientation == 'landscape': 718 ds = min(ph/w, pw/h) 719 else: 720 ds = min(pw/w, ph/h) 721 ow = ds * w 722 oh = ds * h 723 self.figure.set_size_inches((ow, oh)) 724 self.figure.savefig(fname, orientation=orientation, 725 papertype=papertype.lower()) 726 self.figure.set_size_inches((w, h)) 727 print 'Written file %s' % (fname) 728 else: 729 if dpi is None: 730 dpi =150 731 self.figure.savefig(fname,dpi=dpi) 732 print 'Written file %s' % (fname) 733 except IOError, msg: 734 #print 'Failed to save %s: Error msg was\n\n%s' % (fname, err) 735 asaplog.post() 736 asaplog.push('Failed to save %s: Error msg was\n\n%s' % (fname, str(msg))) 737 asaplog.post( 'ERROR' ) 738 return 739 else: 740 #print "Invalid image type. Valid types are:" 741 #print "'ps', 'eps', 'png'" 742 asaplog.push( "Invalid image type. Valid types are:" ) 743 asaplog.push( "'ps', 'eps', 'png', 'svg'" ) 744 asaplog.post('WARN') 745 746 747 ### GUI event methods ### 748 def position(self): 749 """ 750 Use the mouse to get a position from a graph. 751 """ 752 753 def position_disable(event): 754 self.register('button_press', None) 755 print '%.4f, %.4f' % (event.xdata, event.ydata) 756 757 print 'Press any mouse button...' 758 self.register('button_press', position_disable) 759 760 761 def get_region(self): 762 pos = [] 763 print "Please select the bottom/left point" 764 pos.append(self.figure.ginput(n=1, show_clicks=False)[0]) 765 print "Please select the top/right point" 766 pos.append(self.figure.ginput(n=1, show_clicks=False)[0]) 767 return pos 768 769 def get_point(self): 770 print "Please select the point" 771 pt = self.figure.ginput(n=1, show_clicks=False) 772 if pt: 773 return pt[0] 774 else: 775 return None 776 777 def region(self): 778 """ 779 Use the mouse to get a rectangular region from a plot. 780 781 The return value is [x0, y0, x1, y1] in world coordinates. 782 """ 783 784 def region_start(event): 785 self.rect = {'x': event.x, 'y': event.y, 786 'world': [event.xdata, event.ydata, 787 event.xdata, event.ydata]} 788 self.register('button_press', None) 789 self.register('motion_notify', region_draw) 790 self.register('button_release', region_disable) 791 792 def region_draw(event): 793 self.figmgr.toolbar.draw_rubberband(event, event.x, event.y, 794 self.rect['x'], self.rect['y']) 795 796 def region_disable(event): 797 self.register('motion_notify', None) 798 self.register('button_release', None) 799 800 self.rect['world'][2:4] = [event.xdata, event.ydata] 801 print '(%.2f, %.2f) (%.2f, %.2f)' % (self.rect['world'][0], 802 self.rect['world'][1], self.rect['world'][2], 803 self.rect['world'][3]) 804 self.figmgr.toolbar.release(event) 805 806 self.register('button_press', region_start) 807 808 # This has to be modified to block and return the result (currently 809 # printed by region_disable) when that becomes possible in matplotlib. 810 811 return [0.0, 0.0, 0.0, 0.0] 812 813 814 def register(self, type=None, func=None): 815 """ 816 Register, reregister, or deregister events of type 'button_press', 817 'button_release', or 'motion_notify'. 818 819 The specified callback function should have the following signature: 820 821 def func(event) 822 823 where event is an MplEvent instance containing the following data: 824 825 name # Event name. 826 canvas # FigureCanvas instance generating the event. 827 x = None # x position - pixels from left of canvas. 828 y = None # y position - pixels from bottom of canvas. 829 button = None # Button pressed: None, 1, 2, 3. 830 key = None # Key pressed: None, chr(range(255)), shift, 831 win, or control 832 inaxes = None # Axes instance if cursor within axes. 833 xdata = None # x world coordinate. 834 ydata = None # y world coordinate. 835 836 For example: 837 838 def mouse_move(event): 839 print event.xdata, event.ydata 840 841 a = asaplot() 842 a.register('motion_notify', mouse_move) 843 844 If func is None, the event is deregistered. 845 846 Note that in TkAgg keyboard button presses don't generate an event. 847 """ 848 849 if not self.events.has_key(type): return 850 851 if func is None: 852 if self.events[type] is not None: 853 # It's not clear that this does anything. 854 self.canvas.mpl_disconnect(self.events[type]) 855 self.events[type] = None 856 857 # It seems to be necessary to return events to the toolbar. <-- Not ture. 2010.Jul.14.kana. 858 #if type == 'motion_notify': 859 # self.canvas.mpl_connect(type + '_event', 860 # self.figmgr.toolbar.mouse_move) 861 #elif type == 'button_press': 862 # self.canvas.mpl_connect(type + '_event', 863 # self.figmgr.toolbar.press) 864 #elif type == 'button_release': 865 # self.canvas.mpl_connect(type + '_event', 866 # self.figmgr.toolbar.release) 867 868 else: 869 self.events[type] = self.canvas.mpl_connect(type + '_event', func) 870 -
trunk/python/asapplotter.py
r2699 r2700 655 655 return 656 656 657 def set_histogram(self, hist=True, linewidth=None, refresh=True): 658 """ 659 Enable/Disable histogram-like plotting. 660 Parameters: 661 hist: True (default) or False. The fisrt default 662 is taken from the .asaprc setting 663 plotter.histogram 664 linewidth: a line width 665 refresh: True (default) or False. If True, the plot is 666 replotted based on the new parameter setting(s). 667 Otherwise,the parameter(s) are set without replotting. 668 """ 669 self._hist = hist 670 if isinstance(linewidth, float) or isinstance(linewidth, int): 671 from matplotlib import rc as rcp 672 rcp('lines', linewidth=linewidth) 673 if refresh and self._data: self.plot(self._data) 674 657 675 def set_colors(self, colmap, refresh=True): 658 676 """ … … 678 696 # alias for english speakers 679 697 set_colours = set_colors 680 681 def set_histogram(self, hist=True, linewidth=None, refresh=True):682 """683 Enable/Disable histogram-like plotting.684 Parameters:685 hist: True (default) or False. The fisrt default686 is taken from the .asaprc setting687 plotter.histogram688 linewidth: a line width689 refresh: True (default) or False. If True, the plot is690 replotted based on the new parameter setting(s).691 Otherwise,the parameter(s) are set without replotting.692 """693 self._hist = hist694 if isinstance(linewidth, float) or isinstance(linewidth, int):695 from matplotlib import rc as rcp696 rcp('lines', linewidth=linewidth)697 if refresh and self._data: self.plot(self._data)698 698 699 699 def set_linestyles(self, linestyles=None, linewidth=None, refresh=True): … … 921 921 self._maskselection = None 922 922 if refresh: self.plot(self._data) 923 924 def _slice_indeces(self, data):925 mn = self._minmaxx[0]926 mx = self._minmaxx[1]927 asc = data[0] < data[-1]928 start=0929 end = len(data)-1930 inc = 1931 if not asc:932 start = len(data)-1933 end = 0934 inc = -1935 # find min index936 #while start > 0 and data[start] < mn:937 # start+= inc938 minind=start939 for ind in xrange(start,end+inc,inc):940 if data[ind] > mn: break941 minind=ind942 # find max index943 #while end > 0 and data[end] > mx:944 # end-=inc945 #if end > 0: end +=1946 maxind=end947 for ind in xrange(end,start-inc,-inc):948 if data[ind] < mx: break949 maxind=ind950 start=minind951 end=maxind952 if start > end:953 return end,start+1954 elif start < end:955 return start,end+1956 else:957 return start,end958 923 959 924 … … 1300 1265 return userlabel or d[mode] 1301 1266 1267 def _slice_indeces(self, data): 1268 mn = self._minmaxx[0] 1269 mx = self._minmaxx[1] 1270 asc = data[0] < data[-1] 1271 start=0 1272 end = len(data)-1 1273 inc = 1 1274 if not asc: 1275 start = len(data)-1 1276 end = 0 1277 inc = -1 1278 # find min index 1279 #while start > 0 and data[start] < mn: 1280 # start+= inc 1281 minind=start 1282 for ind in xrange(start,end+inc,inc): 1283 if data[ind] > mn: break 1284 minind=ind 1285 # find max index 1286 #while end > 0 and data[end] > mx: 1287 # end-=inc 1288 #if end > 0: end +=1 1289 maxind=end 1290 for ind in xrange(end,start-inc,-inc): 1291 if data[ind] < mx: break 1292 maxind=ind 1293 start=minind 1294 end=maxind 1295 if start > end: 1296 return end,start+1 1297 elif start < end: 1298 return start,end+1 1299 else: 1300 return start,end 1301 1302 1302 def plotazel(self, scan=None, outfile=None): 1303 1303 """
Note:
See TracChangeset
for help on using the changeset viewer.