source: trunk/python/asaplotbase.py@ 2698

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

New Development: No

JIRA Issue: No

Ready for Test: Yes

Interface Changes: No

What Interface Changed:

Test Programs: iterate pages

Put in Release Notes: No

Module(s): asapplotter and sdplot

Description: An attempt to speed-up page iterations in ASAP plotter.


  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 29.9 KB
Line 
1"""
2ASAP plotting class based on matplotlib.
3"""
4
5import sys
6from re import match
7import matplotlib
8
9from matplotlib.figure import Figure, Text
10from matplotlib.font_manager import FontProperties as FP
11from numpy import sqrt
12from matplotlib import rc, rcParams
13from matplotlib.ticker import OldScalarFormatter
14from matplotlib import _pylab_helpers
15
16from asap.parameters import rcParams as asaprcParams
17from asap.logging import asaplog
18
19# API change in mpl >= 0.98
20try:
21 from matplotlib.transforms import blended_transform_factory
22except ImportError:
23 from matplotlib.transforms import blend_xy_sep_transform as blended_transform_factory
24
25mvers = matplotlib.__version__.split(".")
26if int(mvers[0]) == 0 and int(mvers[1]) < 99:
27 #print "Warning: matplotlib version < 0.87. This might cause errors. Please upgrade."
28 asaplog.push( "matplotlib version < 0.99. This might cause errors. Please upgrade." )
29 asaplog.post( 'WARN' )
30
31class asaplotbase:
32 """
33 ASAP plotting base class based on matplotlib.
34 """
35
36 def __init__(self, rows=1, cols=0, title='', size=None, buffering=False):
37 """
38 Create a new instance of the ASAPlot plotting class.
39
40 If rows < 1 then a separate call to set_panels() is required to define
41 the panel layout; refer to the doctext for set_panels().
42 """
43 self.is_dead = False
44 self.figure = Figure(figsize=size, facecolor='#ddddee')
45 self.canvas = None
46
47 self.set_title(title)
48 self.subplots = []
49 if rows > 0:
50 self.set_panels(rows, cols)
51
52 # Set matplotlib default colour sequence.
53 self.colormap = "green red black cyan magenta orange blue purple yellow pink".split()
54
55 c = asaprcParams['plotter.colours']
56 if isinstance(c,str) and len(c) > 0:
57 self.colormap = c.split()
58
59 self.lsalias = {"line": '-', #[1,0],
60 "dashdot": '-.', #[4,2,1,2],
61 "dashed" : '--', #[4,2,4,2],
62 "dotted" : ':', #[1,2],
63 "dashdotdot": [4,2,1,2,1,2],
64 "dashdashdot": [4,2,4,2,1,2]
65 }
66
67 styles = "line dashed dotted dashdot".split()
68 c = asaprcParams['plotter.linestyles']
69 if isinstance(c,str) and len(c) > 0:
70 styles = c.split()
71 s = []
72 for ls in styles:
73 if self.lsalias.has_key(ls):
74 s.append(self.lsalias.get(ls))
75 else:
76 s.append('-')
77 self.linestyles = s
78
79 self.color = 0;
80 self.linestyle = 0;
81 self.attributes = {}
82 self.loc = 0
83
84 self.buffering = buffering
85
86 self.events = {'button_press':None,
87 'button_release':None,
88 'motion_notify':None}
89
90 def clear(self):
91 """
92 Delete all lines from the current subplot.
93 Line numbering will restart from 0.
94 """
95
96 #for i in range(len(self.lines)):
97 # self.delete(i)
98 self.axes.clear()
99 self.color = 0
100 self.lines = []
101 self.subplots[self.i]['lines'] = self.lines
102
103 def palette(self, color, colormap=None, linestyle=0, linestyles=None):
104 if colormap:
105 if isinstance(colormap,list):
106 self.colormap = colormap
107 elif isinstance(colormap,str):
108 self.colormap = colormap.split()
109 if 0 <= color < len(self.colormap):
110 self.color = color
111 if linestyles:
112 self.linestyles = []
113 if isinstance(linestyles,list):
114 styles = linestyles
115 elif isinstance(linestyles,str):
116 styles = linestyles.split()
117 for ls in styles:
118 if self.lsalias.has_key(ls):
119 self.linestyles.append(self.lsalias.get(ls))
120 else:
121 self.linestyles.append(self.lsalias.get('line'))
122 if 0 <= linestyle < len(self.linestyles):
123 self.linestyle = linestyle
124
125 def delete(self, numbers=None):
126 """
127 Delete the 0-relative line number, default is to delete the last.
128 The remaining lines are NOT renumbered.
129 """
130
131 if numbers is None: numbers = [len(self.lines)-1]
132
133 if not hasattr(numbers, '__iter__'):
134 numbers = [numbers]
135
136 for number in numbers:
137 if 0 <= number < len(self.lines):
138 if self.lines[number] is not None:
139 for line in self.lines[number]:
140 line.set_linestyle('None')
141 self.lines[number] = None
142 self.show()
143
144 def get_line(self):
145 """
146 Get the current default line attributes.
147 """
148 return self.attributes
149
150
151 def hist(self, x=None, y=None, fmt=None, add=None):
152 """
153 Plot a histogram. N.B. the x values refer to the start of the
154 histogram bin.
155
156 fmt is the line style as in plot().
157 """
158 from numpy import array
159 from numpy.ma import MaskedArray
160 if x is None:
161 if y is None: return
162 x = range(len(y))
163
164 if len(x) != len(y):
165 return
166 l2 = 2*len(x)
167 x2 = range(l2)
168 y2 = range(12)
169 y2 = range(l2)
170 m2 = range(l2)
171 ymsk = None
172 ydat = None
173 if hasattr(y, "raw_mask"):
174 # numpy < 1.1
175 ymsk = y.raw_mask()
176 ydat = y.raw_data()
177 else:
178 ymsk = y.mask
179 ydat = y.data
180 for i in range(l2):
181 x2[i] = x[i/2]
182 m2[i] = ymsk[i/2]
183
184 y2[0] = 0.0
185 for i in range(1,l2):
186 y2[i] = ydat[(i-1)/2]
187
188 self.plot(x2, MaskedArray(y2,mask=m2,copy=0), fmt, add)
189
190
191 def hold(self, hold=True):
192 """
193 Buffer graphics until subsequently released.
194 """
195 self.buffering = hold
196
197
198 def legend(self, loc=None):
199 """
200 Add a legend to the plot.
201
202 Any other value for loc else disables the legend:
203 1: upper right
204 2: upper left
205 3: lower left
206 4: lower right
207 5: right
208 6: center left
209 7: center right
210 8: lower center
211 9: upper center
212 10: center
213
214 """
215 if isinstance(loc, int):
216 self.loc = None
217 if 0 <= loc <= 10: self.loc = loc
218 else:
219 self.loc = None
220 #self.show()
221
222
223 def plot(self, x=None, y=None, fmt=None, add=None):
224 """
225 Plot the next line in the current frame using the current line
226 attributes. The ASAPlot graphics window will be mapped and raised.
227
228 The argument list works a bit like the matlab plot() function.
229 """
230 if x is None:
231 if y is None: return
232 x = range(len(y))
233
234 elif y is None:
235 y = x
236 x = range(len(y))
237 if fmt is None:
238 line = self.axes.plot(x, y)
239 else:
240 line = self.axes.plot(x, y, fmt)
241 # add a picker to lines for spectral value mode.
242 # matplotlib.axes.plot returns a list of line object (1 element)
243 line[0].set_picker(5.0)
244
245 # Add to an existing line?
246 i = None
247 if add is None or len(self.lines) < add < 0:
248 # Don't add.
249 self.lines.append(line)
250 i = len(self.lines) - 1
251 else:
252 if add == 0: add = len(self.lines)
253 i = add - 1
254 self.lines[i].extend(line)
255
256 # Set/reset attributes for the line.
257 gotcolour = False
258 for k, v in self.attributes.iteritems():
259 if k == 'color': gotcolour = True
260 for segment in self.lines[i]:
261 getattr(segment, "set_%s"%k)(v)
262
263 if not gotcolour and len(self.colormap):
264 for segment in self.lines[i]:
265 getattr(segment, "set_color")(self.colormap[self.color])
266 if len(self.colormap) == 1:
267 getattr(segment, "set_dashes")(self.linestyles[self.linestyle])
268
269 self.color += 1
270 if self.color >= len(self.colormap):
271 self.color = 0
272
273 if len(self.colormap) == 1:
274 self.linestyle += 1
275 if self.linestyle >= len(self.linestyles):
276 self.linestyle = 0
277
278 self.show()
279
280
281 def position(self):
282 """
283 Use the mouse to get a position from a graph.
284 """
285
286 def position_disable(event):
287 self.register('button_press', None)
288 print '%.4f, %.4f' % (event.xdata, event.ydata)
289
290 print 'Press any mouse button...'
291 self.register('button_press', position_disable)
292
293
294 def get_region(self):
295 pos = []
296 print "Please select the bottom/left point"
297 pos.append(self.figure.ginput(n=1, show_clicks=False)[0])
298 print "Please select the top/right point"
299 pos.append(self.figure.ginput(n=1, show_clicks=False)[0])
300 return pos
301
302 def get_point(self):
303 print "Please select the point"
304 pt = self.figure.ginput(n=1, show_clicks=False)
305 if pt:
306 return pt[0]
307 else:
308 return None
309
310 def region(self):
311 """
312 Use the mouse to get a rectangular region from a plot.
313
314 The return value is [x0, y0, x1, y1] in world coordinates.
315 """
316
317 def region_start(event):
318 self.rect = {'x': event.x, 'y': event.y,
319 'world': [event.xdata, event.ydata,
320 event.xdata, event.ydata]}
321 self.register('button_press', None)
322 self.register('motion_notify', region_draw)
323 self.register('button_release', region_disable)
324
325 def region_draw(event):
326 self.figmgr.toolbar.draw_rubberband(event, event.x, event.y,
327 self.rect['x'], self.rect['y'])
328
329 def region_disable(event):
330 self.register('motion_notify', None)
331 self.register('button_release', None)
332
333 self.rect['world'][2:4] = [event.xdata, event.ydata]
334 print '(%.2f, %.2f) (%.2f, %.2f)' % (self.rect['world'][0],
335 self.rect['world'][1], self.rect['world'][2],
336 self.rect['world'][3])
337 self.figmgr.toolbar.release(event)
338
339 self.register('button_press', region_start)
340
341 # This has to be modified to block and return the result (currently
342 # printed by region_disable) when that becomes possible in matplotlib.
343
344 return [0.0, 0.0, 0.0, 0.0]
345
346
347 def register(self, type=None, func=None):
348 """
349 Register, reregister, or deregister events of type 'button_press',
350 'button_release', or 'motion_notify'.
351
352 The specified callback function should have the following signature:
353
354 def func(event)
355
356 where event is an MplEvent instance containing the following data:
357
358 name # Event name.
359 canvas # FigureCanvas instance generating the event.
360 x = None # x position - pixels from left of canvas.
361 y = None # y position - pixels from bottom of canvas.
362 button = None # Button pressed: None, 1, 2, 3.
363 key = None # Key pressed: None, chr(range(255)), shift,
364 win, or control
365 inaxes = None # Axes instance if cursor within axes.
366 xdata = None # x world coordinate.
367 ydata = None # y world coordinate.
368
369 For example:
370
371 def mouse_move(event):
372 print event.xdata, event.ydata
373
374 a = asaplot()
375 a.register('motion_notify', mouse_move)
376
377 If func is None, the event is deregistered.
378
379 Note that in TkAgg keyboard button presses don't generate an event.
380 """
381
382 if not self.events.has_key(type): return
383
384 if func is None:
385 if self.events[type] is not None:
386 # It's not clear that this does anything.
387 self.canvas.mpl_disconnect(self.events[type])
388 self.events[type] = None
389
390 # It seems to be necessary to return events to the toolbar. <-- Not ture. 2010.Jul.14.kana.
391 #if type == 'motion_notify':
392 # self.canvas.mpl_connect(type + '_event',
393 # self.figmgr.toolbar.mouse_move)
394 #elif type == 'button_press':
395 # self.canvas.mpl_connect(type + '_event',
396 # self.figmgr.toolbar.press)
397 #elif type == 'button_release':
398 # self.canvas.mpl_connect(type + '_event',
399 # self.figmgr.toolbar.release)
400
401 else:
402 self.events[type] = self.canvas.mpl_connect(type + '_event', func)
403
404
405 def release(self):
406 """
407 Release buffered graphics.
408 """
409 self.buffering = False
410 self.show()
411
412
413 def save(self, fname=None, orientation=None, dpi=None, papertype=None):
414 """
415 Save the plot to a file.
416
417 fname is the name of the output file. The image format is determined
418 from the file suffix; 'png', 'ps', and 'eps' are recognized. If no
419 file name is specified 'yyyymmdd_hhmmss.png' is created in the current
420 directory.
421 """
422 from asap import rcParams
423 if papertype is None:
424 papertype = rcParams['plotter.papertype']
425 if fname is None:
426 from datetime import datetime
427 dstr = datetime.now().strftime('%Y%m%d_%H%M%S')
428 fname = 'asap'+dstr+'.png'
429
430 d = ['png','.ps','eps', 'svg']
431
432 from os.path import expandvars
433 fname = expandvars(fname)
434
435 if fname[-3:].lower() in d:
436 try:
437 if fname[-3:].lower() == ".ps":
438 from matplotlib import __version__ as mv
439 w = self.figure.get_figwidth()
440 h = self.figure.get_figheight()
441
442 if orientation is None:
443 # oriented
444 if w > h:
445 orientation = 'landscape'
446 else:
447 orientation = 'portrait'
448 from matplotlib.backends.backend_ps import papersize
449 pw,ph = papersize[papertype.lower()]
450 ds = None
451 if orientation == 'landscape':
452 ds = min(ph/w, pw/h)
453 else:
454 ds = min(pw/w, ph/h)
455 ow = ds * w
456 oh = ds * h
457 self.figure.set_size_inches((ow, oh))
458 self.figure.savefig(fname, orientation=orientation,
459 papertype=papertype.lower())
460 self.figure.set_size_inches((w, h))
461 print 'Written file %s' % (fname)
462 else:
463 if dpi is None:
464 dpi =150
465 self.figure.savefig(fname,dpi=dpi)
466 print 'Written file %s' % (fname)
467 except IOError, msg:
468 #print 'Failed to save %s: Error msg was\n\n%s' % (fname, err)
469 asaplog.post()
470 asaplog.push('Failed to save %s: Error msg was\n\n%s' % (fname, str(msg)))
471 asaplog.post( 'ERROR' )
472 return
473 else:
474 #print "Invalid image type. Valid types are:"
475 #print "'ps', 'eps', 'png'"
476 asaplog.push( "Invalid image type. Valid types are:" )
477 asaplog.push( "'ps', 'eps', 'png', 'svg'" )
478 asaplog.post('WARN')
479
480
481 def set_axes(self, what=None, *args, **kwargs):
482 """
483 Set attributes for the axes by calling the relevant Axes.set_*()
484 method. Colour translation is done as described in the doctext
485 for palette().
486 """
487
488 if what is None: return
489 if what[-6:] == 'colour': what = what[:-6] + 'color'
490
491 key = "colour"
492 if kwargs.has_key(key):
493 val = kwargs.pop(key)
494 kwargs["color"] = val
495
496 getattr(self.axes, "set_%s"%what)(*args, **kwargs)
497
498 self.show(hardrefresh=False)
499
500
501 def set_figure(self, what=None, *args, **kwargs):
502 """
503 Set attributes for the figure by calling the relevant Figure.set_*()
504 method. Colour translation is done as described in the doctext
505 for palette().
506 """
507
508 if what is None: return
509 if what[-6:] == 'colour': what = what[:-6] + 'color'
510 #if what[-5:] == 'color' and len(args):
511 # args = (get_colour(args[0]),)
512
513 newargs = {}
514 for k, v in kwargs.iteritems():
515 k = k.lower()
516 if k == 'colour': k = 'color'
517 newargs[k] = v
518
519 getattr(self.figure, "set_%s"%what)(*args, **newargs)
520 self.show(hardrefresh=False)
521
522
523 def set_limits(self, xlim=None, ylim=None):
524 """
525 Set x-, and y-limits for each subplot.
526
527 xlim = [xmin, xmax] as in axes.set_xlim().
528 ylim = [ymin, ymax] as in axes.set_ylim().
529 """
530 for s in self.subplots:
531 self.axes = s['axes']
532 self.lines = s['lines']
533 oldxlim = list(self.axes.get_xlim())
534 oldylim = list(self.axes.get_ylim())
535 if xlim is not None:
536 for i in range(len(xlim)):
537 if xlim[i] is not None:
538 oldxlim[i] = xlim[i]
539 if ylim is not None:
540 for i in range(len(ylim)):
541 if ylim[i] is not None:
542 oldylim[i] = ylim[i]
543 self.axes.set_xlim(oldxlim)
544 self.axes.set_ylim(oldylim)
545 return
546
547
548 def set_line(self, number=None, **kwargs):
549 """
550 Set attributes for the specified line, or else the next line(s)
551 to be plotted.
552
553 number is the 0-relative number of a line that has already been
554 plotted. If no such line exists, attributes are recorded and used
555 for the next line(s) to be plotted.
556
557 Keyword arguments specify Line2D attributes, e.g. color='r'. Do
558
559 import matplotlib
560 help(matplotlib.lines)
561
562 The set_* methods of class Line2D define the attribute names and
563 values. For non-US usage, 'colour' is recognized as synonymous with
564 'color'.
565
566 Set the value to None to delete an attribute.
567
568 Colour translation is done as described in the doctext for palette().
569 """
570
571 redraw = False
572 for k, v in kwargs.iteritems():
573 k = k.lower()
574 if k == 'colour': k = 'color'
575
576 if 0 <= number < len(self.lines):
577 if self.lines[number] is not None:
578 for line in self.lines[number]:
579 getattr(line, "set_%s"%k)(v)
580 redraw = True
581 else:
582 if v is None:
583 del self.attributes[k]
584 else:
585 self.attributes[k] = v
586
587 if redraw: self.show(hardrefresh=False)
588
589
590 #def set_panels(self, rows=1, cols=0, n=-1, nplots=-1, ganged=True):
591 def set_panels(self, rows=1, cols=0, n=-1, nplots=-1, margin=None,ganged=True):
592 """
593 Set the panel layout.
594
595 rows and cols, if cols != 0, specify the number of rows and columns in
596 a regular layout. (Indexing of these panels in matplotlib is row-
597 major, i.e. column varies fastest.)
598
599 cols == 0 is interpreted as a retangular layout that accomodates
600 'rows' panels, e.g. rows == 6, cols == 0 is equivalent to
601 rows == 2, cols == 3.
602
603 0 <= n < rows*cols is interpreted as the 0-relative panel number in
604 the configuration specified by rows and cols to be added to the
605 current figure as its next 0-relative panel number (i). This allows
606 non-regular panel layouts to be constructed via multiple calls. Any
607 other value of n clears the plot and produces a rectangular array of
608 empty panels. The number of these may be limited by nplots.
609 """
610 if n < 0 and len(self.subplots):
611 self.figure.clear()
612 self.set_title()
613
614 if margin:
615 lef, bot, rig, top, wsp, hsp = margin
616 self.figure.subplots_adjust(
617 left=lef,bottom=bot,right=rig,top=top,wspace=wsp,hspace=hsp)
618 del lef,bot,rig,top,wsp,hsp
619
620 if rows < 1: rows = 1
621
622 if cols <= 0:
623 i = int(sqrt(rows))
624 if i*i < rows: i += 1
625 cols = i
626
627 if i*(i-1) >= rows: i -= 1
628 rows = i
629
630 if 0 <= n < rows*cols:
631 i = len(self.subplots)
632
633 self.subplots.append({})
634
635 self.subplots[i]['axes'] = self.figure.add_subplot(rows,
636 cols, n+1)
637 self.subplots[i]['lines'] = []
638
639 if i == 0: self.subplot(0)
640
641 self.rows = 0
642 self.cols = 0
643
644 else:
645 self.subplots = []
646
647 if nplots < 1 or rows*cols < nplots:
648 nplots = rows*cols
649 if ganged:
650 hsp,wsp = None,None
651 if rows > 1: hsp = 0.0001
652 if cols > 1: wsp = 0.0001
653 self.figure.subplots_adjust(wspace=wsp,hspace=hsp)
654 for i in range(nplots):
655 self.subplots.append({})
656 self.subplots[i]['lines'] = []
657 if not ganged:
658 self.subplots[i]['axes'] = self.figure.add_subplot(rows,
659 cols, i+1)
660 if asaprcParams['plotter.axesformatting'] != 'mpl':
661 self.subplots[i]['axes'].xaxis.set_major_formatter(OldScalarFormatter())
662 else:
663 if i == 0:
664 self.subplots[i]['axes'] = self.figure.add_subplot(rows,
665 cols, i+1)
666 if asaprcParams['plotter.axesformatting'] != 'mpl':
667
668 self.subplots[i]['axes'].xaxis.set_major_formatter(OldScalarFormatter())
669 else:
670 self.subplots[i]['axes'] = self.figure.add_subplot(rows,
671 cols, i+1,
672 sharex=self.subplots[0]['axes'],
673 sharey=self.subplots[0]['axes'])
674
675 # Suppress tick labelling for interior subplots.
676 if i <= (rows-1)*cols - 1:
677 if i+cols < nplots:
678 # Suppress x-labels for frames width
679 # adjacent frames
680 for tick in self.subplots[i]['axes'].xaxis.majorTicks:
681 tick.label1On = False
682 #self.subplots[i]['axes'].xaxis.label.set_visible(False)
683 if i%cols:
684 # Suppress y-labels for frames not in the left column.
685 for tick in self.subplots[i]['axes'].yaxis.majorTicks:
686 tick.label1On = False
687 #self.subplots[i]['axes'].yaxis.label.set_visible(False)
688 # disable the first tick of [1:ncol-1] of the last row
689 #if i+1 < nplots:
690 # self.subplots[i]['axes'].xaxis.majorTicks[0].label1On = False
691 # set axes label state for interior subplots.
692 if i%cols:
693 self.subplots[i]['axes'].yaxis.label.set_visible(False)
694 if (i <= (rows-1)*cols - 1) and (i+cols < nplots):
695 self.subplots[i]['axes'].xaxis.label.set_visible(False)
696 self.rows = rows
697 self.cols = cols
698 self.subplot(0)
699 del rows,cols,n,nplots,margin,ganged,i
700
701
702 def tidy(self):
703 # this needs to be exceuted after the first "refresh"
704 nplots = len(self.subplots)
705 if nplots == 1: return
706 for i in xrange(nplots):
707 ax = self.subplots[i]['axes']
708 if i%self.cols:
709 ax.xaxis.majorTicks[0].label1On = False
710 else:
711 if i != 0:
712 ax.yaxis.majorTicks[-1].label1On = False
713 ## set axes label state for interior subplots.
714 #innerax=False
715 #if i%self.cols:
716 # ax.yaxis.label.set_visible(innerax)
717 #if (i <= (self.rows-1)*self.cols - 1) and (i+self.cols < nplots):
718 # ax.xaxis.label.set_visible(innerax)
719
720
721 def set_title(self, title=None):
722 """
723 Set the title of the plot window. Use the previous title if title is
724 omitted.
725 """
726 if title is not None:
727 self.title = title
728
729 self.figure.text(0.5, 0.95, self.title, horizontalalignment='center')
730
731
732 def show(self, hardrefresh=True):
733 """
734 Show graphics dependent on the current buffering state.
735 """
736 if not hardrefresh: return
737 if not self.buffering:
738 if self.loc is not None:
739 for sp in self.subplots:
740 lines = []
741 labels = []
742 i = 0
743 for line in sp['lines']:
744 i += 1
745 if line is not None:
746 lines.append(line[0])
747 lbl = line[0].get_label()
748 if lbl == '':
749 lbl = str(i)
750 labels.append(lbl)
751
752 if len(lines):
753 fp = FP(size=rcParams['legend.fontsize'])
754 #fsz = fp.get_size_in_points() - len(lines)
755 fsz = fp.get_size_in_points() - max(len(lines),self.cols)
756 #fp.set_size(max(fsz,6))
757 fp.set_size(max(fsz,8))
758 sp['axes'].legend(tuple(lines), tuple(labels),
759 self.loc, prop=fp)
760 #else:
761 # sp['axes'].legend((' '))
762
763 from matplotlib.artist import setp
764 fpx = FP(size=rcParams['xtick.labelsize'])
765 xts = fpx.get_size_in_points()- (self.cols)/2
766 fpy = FP(size=rcParams['ytick.labelsize'])
767 yts = fpy.get_size_in_points() - (self.rows)/2
768 fpa = FP(size=rcParams['axes.labelsize'])
769 fpat = FP(size=rcParams['axes.titlesize'])
770 axsize = fpa.get_size_in_points()
771 tsize = fpat.get_size_in_points()-(self.cols)/2
772 for sp in self.subplots:
773 ax = sp['axes']
774 ax.title.set_size(tsize)
775 setp(ax.get_xticklabels(), fontsize=xts)
776 setp(ax.get_yticklabels(), fontsize=yts)
777 off = 0
778 if self.cols > 1: off = self.cols
779 ax.xaxis.label.set_size(axsize-off)
780 off = 0
781 if self.rows > 1: off = self.rows
782 ax.yaxis.label.set_size(axsize-off)
783
784 def subplot(self, i=None, inc=None):
785 """
786 Set the subplot to the 0-relative panel number as defined by one or
787 more invokations of set_panels().
788 """
789 l = len(self.subplots)
790 if l:
791 if i is not None:
792 self.i = i
793
794 if inc is not None:
795 self.i += inc
796
797 self.i %= l
798 self.axes = self.subplots[self.i]['axes']
799 self.lines = self.subplots[self.i]['lines']
800
801 def text(self, *args, **kwargs):
802 """
803 Add text to the figure.
804 """
805 self.figure.text(*args, **kwargs)
806 self.show()
807
808 def vline_with_label(self, x, y, label,
809 location='bottom', rotate=0.0, **kwargs):
810 """
811 Plot a vertical line with label.
812 It takes "world" values fo x and y.
813 """
814 ax = self.axes
815 # need this to suppress autoscaling during this function
816 self.axes.set_autoscale_on(False)
817 ymin = 0.0
818 ymax = 1.0
819 valign = 'center'
820 if location.lower() == 'top':
821 y = max(0.0, y)
822 elif location.lower() == 'bottom':
823 y = min(0.0, y)
824 lbloffset = 0.06
825 # a rough estimate for the bb of the text
826 if rotate > 0.0: lbloffset = 0.03*len(label)
827 peakoffset = 0.01
828 xy = None
829 xy0 = None
830 # matplotlib api change 0.98 is using transform now
831 if hasattr(ax.transData, "inverse_xy_tup"):
832 # get relative coords
833 xy0 = ax.transData.xy_tup((x,y))
834 xy = ax.transAxes.inverse_xy_tup(xy0)
835 else:
836 xy0 = ax.transData.transform((x,y))
837 # get relative coords
838 xy = ax.transAxes.inverted().transform(xy0)
839 if location.lower() == 'top':
840 ymax = 1.0-lbloffset
841 ymin = xy[1]+peakoffset
842 valign = 'bottom'
843 ylbl = ymax+0.01
844 elif location.lower() == 'bottom':
845 ymin = lbloffset
846 ymax = xy[1]-peakoffset
847 valign = 'top'
848 ylbl = ymin-0.01
849 trans = blended_transform_factory(ax.transData, ax.transAxes)
850 l = ax.axvline(x, ymin, ymax, color='black', **kwargs)
851 t = ax.text(x, ylbl ,label, verticalalignment=valign,
852 horizontalalignment='center',
853 rotation=rotate,transform = trans)
854 self.axes.set_autoscale_on(True)
855
856 def _alive(self):
857 # Return True if the GUI alives.
858 if (not self.is_dead) and \
859 self.figmgr and hasattr(self.figmgr, "num"):
860 figid = self.figmgr.num
861 # Make sure figid=0 is what asapplotter expects.
862 # It might be already destroied/overridden by matplotlib
863 # commands or other methods using asaplot.
864 return _pylab_helpers.Gcf.has_fignum(figid) and \
865 (self.figmgr == _pylab_helpers.Gcf.get_fig_manager(figid))
866 return False
Note: See TracBrowser for help on using the repository browser.