SourceForge logo
SourceForge logo
Menu

matplotlib-checkins

From: <md...@us...> - 2007年09月07日 15:23:34
Revision: 3810
 http://matplotlib.svn.sourceforge.net/matplotlib/?rev=3810&view=rev
Author: mdboom
Date: 2007年09月07日 08:23:32 -0700 (2007年9月07日)
Log Message:
-----------
Merged revisions 3806-3809 via svnmerge from 
http://matplotlib.svn.sf.net/svnroot/matplotlib/trunk/matplotlib
........
 r3807 | mdboom | 2007年09月07日 10:34:51 -0400 (2007年9月07日) | 2 lines
 
 Backout stylesheet optimization. Breaks on inkscape and Adobe SVG viewer.
........
 r3808 | mdboom | 2007年09月07日 10:55:55 -0400 (2007年9月07日) | 3 lines
 
 Fix embedded glyph rendering bug revealed by Inkscape and Safari (but
 not Firefox)
........
Modified Paths:
--------------
 branches/transforms/lib/matplotlib/backends/backend_svg.py
Property Changed:
----------------
 branches/transforms/
Property changes on: branches/transforms
___________________________________________________________________
Name: svnmerge-integrated
 - /trunk/matplotlib:1-3805
 + /trunk/matplotlib:1-3809
Modified: branches/transforms/lib/matplotlib/backends/backend_svg.py
===================================================================
--- branches/transforms/lib/matplotlib/backends/backend_svg.py	2007年09月07日 15:02:52 UTC (rev 3809)
+++ branches/transforms/lib/matplotlib/backends/backend_svg.py	2007年09月07日 15:23:32 UTC (rev 3810)
@@ -41,7 +41,6 @@
 self._char_defs = {}
 self.mathtext_parser = MathTextParser('SVG')
 self.fontd = {}
- self._styles = {}
 svgwriter.write(svgProlog%(width,height,width,height))
 
 def _draw_svg_element(self, element, details, gc, rgbFace):
@@ -51,10 +50,9 @@
 else:
 clippath = 'clip-path="url(#%s)"' % clipid
 
- style = self._map_style(self._get_style(gc, rgbFace))
- self._svgwriter.write ('%s<%s class="%s" %s %s/>\n' % (
- cliprect,
- element, style, clippath, details))
+ style = self._get_style(gc, rgbFace)
+ self._svgwriter.write ('%s<%s style="%s" %s %s/>\n' % (
+ cliprect, element, style, clippath, details))
 
 def _get_font(self, prop):
 key = hash(prop)
@@ -82,13 +80,13 @@
 if seq is None:
 dashes = ''
 else:
- dashes = 'stroke-dasharray: %s; stroke-dashoffset: %f;' % (
- ','.join(['%f'%val for val in seq]), offset)
+ dashes = 'stroke-dasharray: %s; stroke-dashoffset: %s;' % (
+ ','.join(['%s'%val for val in seq]), offset)
 
 linewidth = gc.get_linewidth()
 if linewidth:
- return 'fill: %s; stroke: %s; stroke-width: %f; ' \
- 'stroke-linejoin: %s; stroke-linecap: %s; %s opacity: %f' % (
+ return 'fill: %s; stroke: %s; stroke-width: %s; ' \
+ 'stroke-linejoin: %s; stroke-linecap: %s; %s opacity: %s' % (
 fill,
 rgb2hex(gc.get_rgb()),
 linewidth,
@@ -98,16 +96,11 @@
 gc.get_alpha(),
 )
 else:
- return 'fill: %s; opacity: %f' % (\
+ return 'fill: %s; opacity: %s' % (\
 fill,
 gc.get_alpha(),
 )
 
- def _map_style(self, style):
- return self._styles.setdefault(
- style,
- "_%x" % len(self._styles))
- 
 def _get_gc_clip_svg(self, gc):
 cliprect = gc.get_clip_rectangle()
 if cliprect is None:
@@ -119,12 +112,12 @@
 self._clipd[key] = cliprect
 x, y, w, h = cliprect
 y = self.height-(y+h)
- style = self._map_style("stroke: gray; fill: none;")
+ style = "stroke: gray; fill: none;"
 box = """\
 <defs>
 <clipPath id="%(key)s">
- <rect x="%(x)f" y="%(y)f" width="%(w)f" height="%(h)f"
- class="%(style)s"/>
+ <rect x="%(x)s" y="%(y)s" width="%(w)s" height="%(h)s"
+ style="%(style)s"/>
 </clipPath>
 </defs>
 """ % locals()
@@ -144,7 +137,7 @@
 """
 Ignores angles for now
 """
- details = 'cx="%f" cy="%f" rx="%f" ry="%f" transform="rotate(%f %f %f)"' % \
+ details = 'cx="%s" cy="%s" rx="%s" ry="%s" transform="rotate(%1.1f %s %s)"' % \
 (x, self.height-y, width/2.0, height/2.0, -rotation, x, self.height-y)
 self._draw_svg_element('ellipse', details, gc, rgbFace)
 
@@ -163,7 +156,7 @@
 trans[4] += trans[0]
 trans[5] += trans[3]
 trans[5] = -trans[5]
- transstr = 'transform="matrix(%f %f %f %f %f %f)" '%tuple(trans)
+ transstr = 'transform="matrix(%s %s %s %s %s %s)" '%tuple(trans)
 assert trans[1] == 0
 assert trans[2] == 0
 numrows,numcols = im.get_size()
@@ -207,12 +200,12 @@
 hrefstr = filename
 
 self._svgwriter.write (
- '<image x="%f" y="%f" width="%f" height="%f" '
+ '<image x="%s" y="%s" width="%s" height="%s" '
 'xlink:href="%s" %s/>\n'%(x/trans[0], (self.height-y)/trans[3]-h, w, h, hrefstr, transstr)
 )
 
 def draw_line(self, gc, x1, y1, x2, y2):
- details = 'd="M %f,%f L %f,%f"' % (x1, self.height-y1,
+ details = 'd="M%s,%sL%s,%s"' % (x1, self.height-y1,
 x2, self.height-y2)
 self._draw_svg_element('path', details, gc, None)
 
@@ -222,11 +215,11 @@
 raise ValueError('x and y must be the same length')
 
 y = self.height - y
- details = ['d="M %f,%f' % (x[0], y[0])]
+ details = ['d="M%s,%s' % (x[0], y[0])]
 xys = zip(x[1:], y[1:])
- details.extend(['L %f,%f' % tup for tup in xys])
+ details.extend(['L%s,%s' % tup for tup in xys])
 details.append('"')
- details = ' '.join(details)
+ details = ''.join(details)
 self._draw_svg_element('path', details, gc, None)
 
 def draw_point(self, gc, x, y):
@@ -234,12 +227,12 @@
 self.draw_arc(gc, gc.get_rgb(), x, y, 1, 0, 0, 0, 0)
 
 def draw_polygon(self, gc, rgbFace, points):
- details = 'points = "%s"' % ' '.join(['%f,%f'%(x,self.height-y)
+ details = 'points = "%s"' % ' '.join(['%s,%s'%(x,self.height-y)
 for x, y in points])
 self._draw_svg_element('polygon', details, gc, rgbFace)
 
 def draw_rectangle(self, gc, rgbFace, x, y, width, height):
- details = 'width="%f" height="%f" x="%f" y="%f"' % (width, height, x,
+ details = 'width="%s" height="%s" x="%s" y="%s"' % (width, height, x,
 self.height-y-height)
 self._draw_svg_element('rect', details, gc, rgbFace)
 
@@ -260,12 +253,11 @@
 
 if rcParams['svg.embed_char_paths']:
 svg = ['<g transform="']
- if angle!=0:
- # Inkscape doesn't support rotate(angle x y)
- svg.append('translate(%f,%f) rotate(%1.1f) ' % (x,y,-angle))
- else:
- svg.append('translate(%f,%f)' % (x,y))
- svg.append(' scale(%f)">\n' % (fontsize / self.FONT_SCALE))
+ if angle != 0:
+ svg.append('translate(%s,%s)rotate(%1.1f)' % (x,y,-angle))
+ elif x != 0 or y != 0:
+ svg.append('translate(%s,%s)' % (x, y))
+ svg.append('scale(%s)">\n' % (fontsize / self.FONT_SCALE))
 
 cmap = font.get_charmap()
 lastgind = None
@@ -286,21 +278,24 @@
 lastgind = gind
 currx += kern/64.0
 
- svg.append('<use xlink:href="#%s" transform="translate(%s)"/>\n'
- % (charid, currx * (self.FONT_SCALE / fontsize)))
-
+ svg.append('<use xlink:href="#%s"' % charid)
+ if currx != 0:
+ svg.append(' transform="translate(%s)"' %
+ (currx * (self.FONT_SCALE / fontsize)))
+ svg.append('/>\n')
 currx += (glyph.linearHoriAdvance / 65536.0)
 svg.append('</g>\n')
 svg = ''.join(svg)
 else:
 style = 'font-size: %f; font-family: %s; font-style: %s; fill: %s;'%(fontsize, fontfamily,fontstyle, color)
- style_number = self._map_style(style)
 if angle!=0:
- transform = 'transform="translate(%f,%f) rotate(%1.1f) translate(%f,%f)"' % (x,y,-angle,-x,-y) # Inkscape doesn't support rotate(angle x y)
- else: transform = ''
+ transform = 'transform="translate(%s,%s) rotate(%1.1f) translate(%s,%s)"' % (x,y,-angle,-x,-y)
+ # Inkscape doesn't support rotate(angle x y)
+ else:
+ transform = ''
 
 svg = """\
-<text class="%(style_number)s" x="%(x)f" y="%(y)f" %(transform)s>%(thetext)s</text>
+<text style="%(style)s" x="%(x)s" y="%(y)s" %(transform)s>%(thetext)s</text>
 """ % locals()
 self._svgwriter.write (svg)
 
@@ -313,16 +308,17 @@
 font.set_size(self.FONT_SCALE, 72)
 ps_name = font.get_sfnt()[(1,0,0,6)]
 char_id = urllib.quote('%s-%d' % (ps_name, ord(char)))
- if char_id in self._char_defs:
- return char_id
+ char_num, path = self._char_defs.get(char_id, (None, None))
+ if char_num is not None:
+ return char_num
 
 path_data = []
 glyph = font.load_char(ord(char), flags=LOAD_NO_HINTING)
 currx, curry = 0.0, 0.0
 for step in glyph.path:
 if step[0] == 0: # MOVE_TO
- path_data.append("m%s %s" %
- (step[1] - currx, -step[2] - curry))
+ path_data.append("M%s %s" %
+ (step[1], -step[2]))
 elif step[0] == 1: # LINE_TO
 path_data.append("l%s %s" %
 (step[1] - currx, -step[2] - curry))
@@ -336,15 +332,16 @@
 step[3] - currx, -step[4] - curry,
 step[5] - currx, -step[6] - curry))
 elif step[0] == 4: # ENDPOLY
- path_data.append("Z")
+ path_data.append("z")
+ currx, curry = 0.0, 0.0
 
 if step[0] != 4:
 currx, curry = step[-2], -step[-1]
- path_element = '<path id="%s" d="%s"/>\n' % (char_id, " ".join(path_data))
+ char_num = 'c_%x' % len(self._char_defs)
+ path_element = '<path id="%s" d="%s"/>\n' % (char_num, ''.join(path_data))
+ self._char_defs[char_id] = (char_num, path_element)
+ return char_num
 
- self._char_defs[char_id] = path_element
- return char_id
-
 def _draw_mathtext(self, gc, x, y, s, prop, angle):
 """
 Draw math text using matplotlib.mathtext
@@ -358,25 +355,24 @@
 self.open_group("mathtext")
 
 style = "fill: %s" % color
- style_number = self._map_style(style)
 
 if rcParams['svg.embed_char_paths']:
- svg = ['<g class="%s" transform="' % style_number]
+ svg = ['<g style="%s" transform="' % style]
 if angle != 0:
- svg.append('translate(%f,%f) rotate(%1.1f)'
+ svg.append('translate(%s,%s)rotate(%1.1f)'
 % (x,y,-angle) )
 else:
- svg.append('translate(%f,%f)' % (x, y))
+ svg.append('translate(%s,%s)' % (x, y))
 svg.append('">\n')
 
 for font, fontsize, thetext, new_x, new_y_mtc, metrics in svg_glyphs:
 charid = self._add_char_def(font, thetext)
 
- svg.append('<use xlink:href="#%s" transform="translate(%s, %s) scale(%s)"/>\n' %
+ svg.append('<use xlink:href="#%s" transform="translate(%s,%s)scale(%s)"/>\n' %
 (charid, new_x, -new_y_mtc, fontsize / self.FONT_SCALE))
 svg.append('</g>\n')
 else: # not rcParams['svg.embed_char_paths']
- svg = ['<text class="%s" x="%f" y="%f"' % (style_number, x, y)]
+ svg = ['<text style="%s" x="%f" y="%f"' % (style, x, y)]
 
 if angle != 0:
 svg.append(' transform="translate(%f,%f) rotate(%1.1f) translate(%f,%f)"'
@@ -388,19 +384,18 @@
 for font, fontsize, thetext, new_x, new_y_mtc, metrics in svg_glyphs:
 new_y = - new_y_mtc
 style = "font-size: %f; font-family: %s" % (fontsize, font.family_name)
- style_number = self._map_style(style)
 
- svg.append('<tspan class="%s"' % style_number)
+ svg.append('<tspan style="%s"' % style)
 xadvance = metrics.advance
- svg.append(' textLength="%f"' % xadvance)
+ svg.append(' textLength="%s"' % xadvance)
 
 dx = new_x - curr_x
 if dx != 0.0:
- svg.append(' dx="%f"' % dx)
+ svg.append(' dx="%s"' % dx)
 
 dy = new_y - curr_y
 if dy != 0.0:
- svg.append(' dy="%f"' % dy)
+ svg.append(' dy="%s"' % dy)
 
 thetext = escape_xml_text(thetext)
 
@@ -412,13 +407,13 @@
 svg.append('</text>\n')
 
 if len(svg_rects):
- style_number = self._map_style("fill: black; stroke: none")
- svg.append('<g class="%s" transform="' % style_number)
+ style = "fill: black; stroke: none"
+ svg.append('<g style="%s" transform="' % style)
 if angle != 0:
- svg.append('translate(%f,%f) rotate(%1.1f)'
+ svg.append('translate(%s,%s) rotate(%1.1f)'
 % (x,y,-angle) )
 else:
- svg.append('translate(%f,%f)' % (x, y))
+ svg.append('translate(%s,%s)' % (x, y))
 svg.append('">\n')
 
 for x, y, width, height in svg_rects:
@@ -432,16 +427,9 @@
 write = self._svgwriter.write
 if len(self._char_defs):
 write('<defs id="fontpaths">\n')
- for path in self._char_defs.values():
+ for char_num, path in self._char_defs.values():
 write(path)
 write('</defs>\n')
- if len(self._styles):
- write('<style type="text/css">\n')
- styles = self._styles.items()
- styles.sort()
- for style, number in styles:
- write('.%s { %s }\n' % (number, style))
- write('</style>\n')
 write('</svg>\n')
 
 def flipy(self):
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
From: <md...@us...> - 2007年09月07日 18:53:59
Revision: 3813
 http://matplotlib.svn.sourceforge.net/matplotlib/?rev=3813&view=rev
Author: mdboom
Date: 2007年09月07日 11:53:51 -0700 (2007年9月07日)
Log Message:
-----------
Merged revisions 3810-3812 via svnmerge from 
http://matplotlib.svn.sf.net/svnroot/matplotlib/trunk/matplotlib
........
 r3811 | mdboom | 2007年09月07日 14:07:43 -0400 (2007年9月07日) | 2 lines
 
 Note that .bmp is no longer an alias for .raw
........
 r3812 | mdboom | 2007年09月07日 14:08:43 -0400 (2007年9月07日) | 2 lines
 
 Turn svg.embed_char_paths on by default.
........
Modified Paths:
--------------
 branches/transforms/CHANGELOG
 branches/transforms/lib/matplotlib/config/mplconfig.py
 branches/transforms/lib/matplotlib/config/rcsetup.py
 branches/transforms/lib/matplotlib/rcsetup.py
 branches/transforms/matplotlibrc.template
Property Changed:
----------------
 branches/transforms/
Property changes on: branches/transforms
___________________________________________________________________
Name: svnmerge-integrated
 - /trunk/matplotlib:1-3809
 + /trunk/matplotlib:1-3812
Modified: branches/transforms/CHANGELOG
===================================================================
--- branches/transforms/CHANGELOG	2007年09月07日 18:08:43 UTC (rev 3812)
+++ branches/transforms/CHANGELOG	2007年09月07日 18:53:51 UTC (rev 3813)
@@ -1,3 +1,5 @@
+2007年09月06日 .bmp file format is now longer an alias for .raw
+
 2007年09月07日 Added clip path support to pdf backend. - JKS
 
 2007年09月06日 Fixed a bug in the embedding of Type 1 fonts in PDF.
Modified: branches/transforms/lib/matplotlib/config/mplconfig.py
===================================================================
--- branches/transforms/lib/matplotlib/config/mplconfig.py	2007年09月07日 18:08:43 UTC (rev 3812)
+++ branches/transforms/lib/matplotlib/config/mplconfig.py	2007年09月07日 18:53:51 UTC (rev 3813)
@@ -101,7 +101,7 @@
 class svg(TConfig):
 image_inline = T.true
 image_noscale = T.false
- embed_chars = T.false
+ embed_chars = T.true
 
 class lines(TConfig):
 linewidth = T.Float(1.0)
Modified: branches/transforms/lib/matplotlib/config/rcsetup.py
===================================================================
--- branches/transforms/lib/matplotlib/config/rcsetup.py	2007年09月07日 18:08:43 UTC (rev 3812)
+++ branches/transforms/lib/matplotlib/config/rcsetup.py	2007年09月07日 18:53:51 UTC (rev 3813)
@@ -466,7 +466,7 @@
 'pdf.fonttype' : [3, validate_fonttype], # 3 (Type3) or 42 (Truetype)
 'svg.image_inline' : [True, validate_bool], # write raster image data directly into the svg file
 'svg.image_noscale' : [False, validate_bool], # suppress scaling of raster data embedded in SVG
- 'svg.embed_char_paths' : [False, validate_bool], # True to save all characters as paths in the SVG
+ 'svg.embed_char_paths' : [True, validate_bool], # True to save all characters as paths in the SVG
 'plugins.directory' : ['.matplotlib_plugins', str], # where plugin directory is locate
 
 }
Modified: branches/transforms/lib/matplotlib/rcsetup.py
===================================================================
--- branches/transforms/lib/matplotlib/rcsetup.py	2007年09月07日 18:08:43 UTC (rev 3812)
+++ branches/transforms/lib/matplotlib/rcsetup.py	2007年09月07日 18:53:51 UTC (rev 3813)
@@ -466,7 +466,7 @@
 'pdf.fonttype' : [3, validate_fonttype], # 3 (Type3) or 42 (Truetype)
 'svg.image_inline' : [True, validate_bool], # write raster image data directly into the svg file
 'svg.image_noscale' : [False, validate_bool], # suppress scaling of raster data embedded in SVG
- 'svg.embed_char_paths' : [False, validate_bool], # True to save all characters as paths in the SVG
+ 'svg.embed_char_paths' : [True, validate_bool], # True to save all characters as paths in the SVG
 'plugins.directory' : ['.matplotlib_plugins', str], # where plugin directory is locate
 
 }
Modified: branches/transforms/matplotlibrc.template
===================================================================
--- branches/transforms/matplotlibrc.template	2007年09月07日 18:08:43 UTC (rev 3812)
+++ branches/transforms/matplotlibrc.template	2007年09月07日 18:53:51 UTC (rev 3813)
@@ -292,7 +292,7 @@
 # svg backend params
 #svg.image_inline : True # write raster image data directly into the svg file
 #svg.image_noscale : False # suppress scaling of raster data embedded in SVG
-#svg.embed_chars : False # embed character outlines in the SVG file
+#svg.embed_chars : True # embed character outlines in the SVG file
 
 # Set the verbose flags. This controls how much information
 # matplotlib gives you at runtime and where it goes. The verbosity
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
From: <md...@us...> - 2007年09月10日 17:45:18
Revision: 3824
 http://matplotlib.svn.sourceforge.net/matplotlib/?rev=3824&view=rev
Author: mdboom
Date: 2007年09月10日 10:45:15 -0700 (2007年9月10日)
Log Message:
-----------
Merged revisions 3813-3823 via svnmerge from 
http://matplotlib.svn.sf.net/svnroot/matplotlib/trunk/matplotlib
........
 r3814 | jouni | 2007年09月07日 15:45:48 -0400 (2007年9月07日) | 3 lines
 
 In backend_pdf usetex, gather consecutive characters with same x
 coordinate and same font into strings.
........
 r3815 | mdboom | 2007年09月07日 16:28:01 -0400 (2007年9月07日) | 3 lines
 
 Support characters composed of multiple characters. Only one
 supported at the moment is AA (angstrom).
........
 r3816 | jouni | 2007年09月07日 16:43:20 -0400 (2007年9月07日) | 2 lines
 
 Return widths of glyphs to caller
........
 r3817 | efiring | 2007年09月08日 19:53:06 -0400 (2007年9月08日) | 2 lines
 
 Delete gd and paint backends.
........
 r3818 | efiring | 2007年09月08日 20:41:17 -0400 (2007年9月08日) | 2 lines
 
 Removed matplotlibrc; it is generated by setup.py.
........
 r3819 | efiring | 2007年09月09日 18:41:36 -0400 (2007年9月09日) | 2 lines
 
 Factored plotting part of pylab.py into pyplot.py
........
 r3820 | efiring | 2007年09月09日 21:42:39 -0400 (2007年9月09日) | 2 lines
 
 Numpification and cleanup of examples
........
 r3821 | efiring | 2007年09月10日 02:55:10 -0400 (2007年9月10日) | 2 lines
 
 Removed obsolete and broken methods from Axes and PolarAxes
........
Modified Paths:
--------------
 branches/transforms/API_CHANGES
 branches/transforms/CHANGELOG
 branches/transforms/boilerplate.py
 branches/transforms/examples/animation_blit.py
 branches/transforms/examples/animation_blit_fltk.py
 branches/transforms/examples/animation_blit_qt.py
 branches/transforms/examples/animation_blit_qt4.py
 branches/transforms/examples/animation_blit_tk.py
 branches/transforms/examples/animation_blit_wx.py
 branches/transforms/examples/backend_driver.py
 branches/transforms/examples/clippedline.py
 branches/transforms/examples/collections_demo.py
 branches/transforms/examples/color_by_yvalue.py
 branches/transforms/examples/contourf_demo.py
 branches/transforms/examples/data_helper.py
 branches/transforms/examples/dynamic_demo_wx.py
 branches/transforms/examples/dynamic_image_wxagg.py
 branches/transforms/examples/dynamic_image_wxagg2.py
 branches/transforms/examples/embedding_in_gtk.py
 branches/transforms/examples/embedding_in_gtk2.py
 branches/transforms/examples/embedding_in_gtk3.py
 branches/transforms/examples/embedding_in_qt.py
 branches/transforms/examples/embedding_in_qt4.py
 branches/transforms/examples/embedding_in_tk.py
 branches/transforms/examples/embedding_in_tk2.py
 branches/transforms/examples/embedding_in_wx.py
 branches/transforms/examples/embedding_in_wx2.py
 branches/transforms/examples/embedding_in_wx3.py
 branches/transforms/examples/embedding_in_wx4.py
 branches/transforms/examples/gtk_spreadsheet.py
 branches/transforms/examples/histogram_demo_canvasagg.py
 branches/transforms/examples/image_masked.py
 branches/transforms/examples/mathtext_wx.py
 branches/transforms/examples/mpl_with_glade.py
 branches/transforms/examples/multi_image.py
 branches/transforms/examples/pcolor_nonuniform.py
 branches/transforms/examples/polar_bar.py
 branches/transforms/examples/polar_demo.py
 branches/transforms/examples/polar_legend.py
 branches/transforms/examples/poly_editor.py
 branches/transforms/examples/printing_in_wx.py
 branches/transforms/examples/pythonic_matplotlib.py
 branches/transforms/examples/rc_traits.py
 branches/transforms/examples/scatter_masked.py
 branches/transforms/examples/strip_chart_demo.py
 branches/transforms/examples/tex_demo.py
 branches/transforms/examples/tex_unicode_demo.py
 branches/transforms/examples/vline_demo.py
 branches/transforms/examples/webapp_demo.py
 branches/transforms/examples/wxcursor_demo.py
 branches/transforms/lib/matplotlib/__init__.py
 branches/transforms/lib/matplotlib/axes.py
 branches/transforms/lib/matplotlib/backends/__init__.py
 branches/transforms/lib/matplotlib/backends/backend_pdf.py
 branches/transforms/lib/matplotlib/config/mplconfig.py
 branches/transforms/lib/matplotlib/config/rcsetup.py
 branches/transforms/lib/matplotlib/dviread.py
 branches/transforms/lib/matplotlib/mathtext.py
 branches/transforms/lib/matplotlib/mlab.py
 branches/transforms/lib/matplotlib/mpl-data/matplotlib.conf
 branches/transforms/lib/matplotlib/pylab.py
 branches/transforms/setupext.py
Added Paths:
-----------
 branches/transforms/lib/matplotlib/pyplot.py
Removed Paths:
-------------
 branches/transforms/examples/anim_tk.py
 branches/transforms/examples/gdtest.py
 branches/transforms/examples/image_demo_na.py
 branches/transforms/lib/matplotlib/backends/backend_gd.py
 branches/transforms/lib/matplotlib/backends/backend_paint.py
 branches/transforms/lib/matplotlib/mpl-data/matplotlibrc
Property Changed:
----------------
 branches/transforms/
Property changes on: branches/transforms
___________________________________________________________________
Name: svnmerge-integrated
 - /trunk/matplotlib:1-3812
 + /trunk/matplotlib:1-3823
Modified: branches/transforms/API_CHANGES
===================================================================
--- branches/transforms/API_CHANGES	2007年09月10日 17:40:47 UTC (rev 3823)
+++ branches/transforms/API_CHANGES	2007年09月10日 17:45:15 UTC (rev 3824)
@@ -1,3 +1,5 @@
+ The gd and paint backends have been deleted.
+
 The errorbar method and function now accept additional kwargs
 so that upper and lower limits can be indicated by capping the
 bar with a caret instead of a straight line segment.
Modified: branches/transforms/CHANGELOG
===================================================================
--- branches/transforms/CHANGELOG	2007年09月10日 17:40:47 UTC (rev 3823)
+++ branches/transforms/CHANGELOG	2007年09月10日 17:45:15 UTC (rev 3824)
@@ -1,3 +1,16 @@
+2007年09月09日 Split out the plotting part of pylab and put it in
+ pyplot.py; removed numerix from the remaining pylab.py,
+ which imports everything from pyplot.py. The intention
+ is that apart from cleanups, the result of importing
+ from pylab is nearly unchanged, but there is the
+ new alternative of importing from pyplot to get
+ the state-engine graphics without all the numeric
+ functions.
+ Numpified examples; deleted two that were obsolete;
+ modified some to use pyplot. - EF
+
+2007年09月08日 Eliminated gd and paint backends - EF
+
 2007年09月06日 .bmp file format is now longer an alias for .raw
 
 2007年09月07日 Added clip path support to pdf backend. - JKS
@@ -6,17 +19,17 @@
 Now it doesn't crash Preview.app. - JKS
 
 2007年09月06日 Refactored image saving code so that all GUI backends can
-	 save most image types. See FILETYPES for a matrix of
-	 backends and their supported file types. 
-	 Backend canvases should no longer write their own print_figure()
-	 method -- instead they should write a print_xxx method for
-	 each filetype they can output and add an entry to their
-	 class-scoped filetypes dictionary. - MGD
+ save most image types. See FILETYPES for a matrix of
+ backends and their supported file types.
+ Backend canvases should no longer write their own print_figure()
+ method -- instead they should write a print_xxx method for
+ each filetype they can output and add an entry to their
+ class-scoped filetypes dictionary. - MGD
 
 2007年09月05日 Fixed Qt version reporting in setupext.py - DSD
 
 2007年09月04日 Embedding Type 1 fonts in PDF, and thus usetex support
- via dviread, sort of works. To test, enable it by 
+ via dviread, sort of works. To test, enable it by
 renaming _draw_tex to draw_tex. - JKS
 
 2007年09月03日 Added ability of errorbar show limits via caret or
Modified: branches/transforms/boilerplate.py
===================================================================
--- branches/transforms/boilerplate.py	2007年09月10日 17:40:47 UTC (rev 3823)
+++ branches/transforms/boilerplate.py	2007年09月10日 17:45:15 UTC (rev 3824)
@@ -29,7 +29,7 @@
 return ret
 if Axes.%(func)s.__doc__ is not None:
 %(func)s.__doc__ = dedent(Axes.%(func)s.__doc__) + \"\"\"
-Addition kwargs: hold = [True|False] overrides default hold state\"\"\"
+Additional kwargs: hold = [True|False] overrides default hold state\"\"\"
 """
 
 _fmtmisc = """\
@@ -74,6 +74,8 @@
 'plot',
 'plot_date',
 'psd',
+ 'quiver',
+ 'quiverkey',
 'scatter',
 'semilogx',
 'semilogy',
@@ -82,8 +84,6 @@
 'stem',
 'step',
 'vlines',
- 'quiver',
- 'quiverkey',
 'xcorr',
 )
 
@@ -104,7 +104,6 @@
 'pcolormesh' : 'gci._current = ret',
 'imshow' : 'gci._current = ret',
 'spy' : 'gci._current = ret',
- 'quiver2' : 'gci._current = ret',
 'quiver' : 'gci._current = ret',
 'specgram' : 'gci._current = ret[-1]',
 
@@ -129,11 +128,13 @@
 # This function was autogenerated by boilerplate.py. Do not edit as
 # changes will be lost
 def %(name)s():
- 'set the default colormap to %(name)s and apply to current image if any. See help(colormaps) for more information'
+ '''
+ set the default colormap to %(name)s and apply to current image if any.
+ See help(colormaps) for more information
+ '''
 rc('image', cmap='%(name)s')
 im = gci()
 
-
 if im is not None:
 im.set_cmap(cm.%(name)s)
 draw_if_interactive()
Deleted: branches/transforms/examples/anim_tk.py
===================================================================
--- branches/transforms/examples/anim_tk.py	2007年09月10日 17:40:47 UTC (rev 3823)
+++ branches/transforms/examples/anim_tk.py	2007年09月10日 17:45:15 UTC (rev 3824)
@@ -1,49 +0,0 @@
-# deprecated - this example is no longer needed. Follow the model of
-# anim.py to use interaction = True to avoid all the cruft of timers,
-# callbacks and the likes used here
-
-#!/usr/bin/env python2.3
-
-import matplotlib
-matplotlib.use('TkAgg')
-import pylab
-
-#import Tkinter as Tk
-import matplotlib.numerix as numerix
-fig = pylab.figure(1)
-ind = numerix.arange(60)
-
-
-
-x_tmp=[]
-for i in range(100):
- x_tmp.append(numerix.sin((ind+i)*numerix.pi/15.0))
-
-X=numerix.array(x_tmp)
-
-
-lines = pylab.plot(X[:,0],'o')
-
-manager = pylab.get_current_fig_manager()
-
-def updatefig(*args):
- updatefig.count += 1
- lines[0].set_ydata(X[:,updatefig.count%60])
- manager.canvas.draw()
- return updatefig.count
-updatefig.count=-1
-
-def run(*args):
- print 'called run'
-
- import time
- tstart = time.time()
- while 1:
- cnt = updatefig()
- if cnt==100: break
- print 'elapsed', 100.0/(time.time() - tstart)
-
-import Tkinter as Tk
-manager.window.after(10, run)
-manager.show()
-Tk.mainloop()
Modified: branches/transforms/examples/animation_blit.py
===================================================================
--- branches/transforms/examples/animation_blit.py	2007年09月10日 17:40:47 UTC (rev 3823)
+++ branches/transforms/examples/animation_blit.py	2007年09月10日 17:45:15 UTC (rev 3824)
@@ -10,7 +10,7 @@
 
 import matplotlib
 matplotlib.use('GTKAgg')
-import matplotlib.numerix as nx
+import numpy as npy
 import pylab as p
 
 
@@ -21,8 +21,8 @@
 p.grid() # to ensure proper background restore
 
 # create the initial line
-x = nx.arange(0,2*nx.pi,0.01)
-line, = p.plot(x, nx.sin(x), animated=True, lw=2)
+x = npy.arange(0,2*npy.pi,0.01)
+line, = p.plot(x, npy.sin(x), animated=True, lw=2)
 
 # for profiling
 tstart = time.time()
@@ -34,7 +34,7 @@
 # restore the clean slate background
 canvas.restore_region(update_line.background)
 # update the data
- line.set_ydata(nx.sin(x+update_line.cnt/10.0))
+ line.set_ydata(npy.sin(x+update_line.cnt/10.0))
 # just draw the animated artist
 try:
 ax.draw_artist(line)
Modified: branches/transforms/examples/animation_blit_fltk.py
===================================================================
--- branches/transforms/examples/animation_blit_fltk.py	2007年09月10日 17:40:47 UTC (rev 3823)
+++ branches/transforms/examples/animation_blit_fltk.py	2007年09月10日 17:45:15 UTC (rev 3824)
@@ -3,7 +3,7 @@
 import matplotlib
 matplotlib.use('FltkAgg')
 import pylab as p
-import matplotlib.numerix as nx
+import numpy as nx
 import time
 
 
Modified: branches/transforms/examples/animation_blit_qt.py
===================================================================
--- branches/transforms/examples/animation_blit_qt.py	2007年09月10日 17:40:47 UTC (rev 3823)
+++ branches/transforms/examples/animation_blit_qt.py	2007年09月10日 17:45:15 UTC (rev 3824)
@@ -15,7 +15,7 @@
 ITERS = 1000
 
 import pylab as p
-import matplotlib.numerix as nx
+import numpy as npy
 import time
 
 class BlitQT(QObject):
@@ -27,8 +27,8 @@
 self.cnt = 0
 
 # create the initial line
- self.x = nx.arange(0,2*nx.pi,0.01)
- self.line, = p.plot(self.x, nx.sin(self.x), animated=True, lw=2)
+ self.x = npy.arange(0,2*npy.pi,0.01)
+ self.line, = p.plot(self.x, npy.sin(self.x), animated=True, lw=2)
 
 self.background = None
 
@@ -39,7 +39,7 @@
 # restore the clean slate background
 self.canvas.restore_region(self.background)
 # update the data
- self.line.set_ydata(nx.sin(self.x+self.cnt/10.0))
+ self.line.set_ydata(npy.sin(self.x+self.cnt/10.0))
 # just draw the animated artist
 self.ax.draw_artist(self.line)
 # just redraw the axes rectangle
Modified: branches/transforms/examples/animation_blit_qt4.py
===================================================================
--- branches/transforms/examples/animation_blit_qt4.py	2007年09月10日 17:40:47 UTC (rev 3823)
+++ branches/transforms/examples/animation_blit_qt4.py	2007年09月10日 17:45:15 UTC (rev 3824)
@@ -10,7 +10,7 @@
 ITERS = 1000
 
 import pylab as p
-import matplotlib.numerix as nx
+import numpy as npy
 import time
 
 class BlitQT(QtCore.QObject):
@@ -22,8 +22,8 @@
 self.cnt = 0
 
 # create the initial line
- self.x = nx.arange(0,2*nx.pi,0.01)
- self.line, = p.plot(self.x, nx.sin(self.x), animated=True, lw=2)
+ self.x = npy.arange(0,2*npy.pi,0.01)
+ self.line, = p.plot(self.x, npy.sin(self.x), animated=True, lw=2)
 
 self.background = None
 
@@ -34,7 +34,7 @@
 # restore the clean slate background
 self.canvas.restore_region(self.background)
 # update the data
- self.line.set_ydata(nx.sin(self.x+self.cnt/10.0))
+ self.line.set_ydata(npy.sin(self.x+self.cnt/10.0))
 # just draw the animated artist
 self.ax.draw_artist(self.line)
 # just redraw the axes rectangle
Modified: branches/transforms/examples/animation_blit_tk.py
===================================================================
--- branches/transforms/examples/animation_blit_tk.py	2007年09月10日 17:40:47 UTC (rev 3823)
+++ branches/transforms/examples/animation_blit_tk.py	2007年09月10日 17:45:15 UTC (rev 3824)
@@ -6,7 +6,7 @@
 
 import sys
 import pylab as p
-import matplotlib.numerix as nx
+import numpy as npy
 import time
 
 ax = p.subplot(111)
@@ -14,8 +14,8 @@
 
 
 # create the initial line
-x = nx.arange(0,2*nx.pi,0.01)
-line, = p.plot(x, nx.sin(x), animated=True, lw=2)
+x = npy.arange(0,2*npy.pi,0.01)
+line, = p.plot(x, npy.sin(x), animated=True, lw=2)
 
 def run(*args):
 background = canvas.copy_from_bbox(ax.bbox)
@@ -26,7 +26,7 @@
 # restore the clean slate background
 canvas.restore_region(background)
 # update the data
- line.set_ydata(nx.sin(x+run.cnt/10.0))
+ line.set_ydata(npy.sin(x+run.cnt/10.0))
 # just draw the animated artist
 ax.draw_artist(line)
 # just redraw the axes rectangle
Modified: branches/transforms/examples/animation_blit_wx.py
===================================================================
--- branches/transforms/examples/animation_blit_wx.py	2007年09月10日 17:40:47 UTC (rev 3823)
+++ branches/transforms/examples/animation_blit_wx.py	2007年09月10日 17:45:15 UTC (rev 3824)
@@ -12,7 +12,7 @@
 import wx
 import sys
 import pylab as p
-import matplotlib.numerix as nx
+import numpy as npy
 import time
 
 
@@ -30,8 +30,8 @@
 p.grid() # to ensure proper background restore
 
 # create the initial line
-x = nx.arange(0,2*nx.pi,0.01)
-line, = p.plot(x, nx.sin(x), animated=True, lw=2)
+x = npy.arange(0,2*npy.pi,0.01)
+line, = p.plot(x, npy.sin(x), animated=True, lw=2)
 
 # for profiling
 tstart = time.time()
@@ -46,7 +46,7 @@
 # restore the clean slate background
 canvas.restore_region(update_line.background)
 # update the data
- line.set_ydata(nx.sin(x+update_line.cnt/10.0))
+ line.set_ydata(npy.sin(x+update_line.cnt/10.0))
 # just draw the animated artist
 ax.draw_artist(line)
 # just redraw the axes rectangle
Modified: branches/transforms/examples/backend_driver.py
===================================================================
--- branches/transforms/examples/backend_driver.py	2007年09月10日 17:40:47 UTC (rev 3823)
+++ branches/transforms/examples/backend_driver.py	2007年09月10日 17:45:15 UTC (rev 3824)
@@ -42,7 +42,6 @@
 'histogram_demo.py',
 'image_demo.py',
 'image_demo2.py',
- 'image_demo_na.py',
 'image_masked.py',
 'image_origin.py',
 'invert_axes.py',
@@ -158,7 +157,7 @@
 
 if __name__ == '__main__':
 times = {}
- default_backends = ['Agg', 'PS', 'SVG', 'Template']
+ default_backends = ['Agg', 'PS', 'SVG', 'PDF', 'Template']
 if sys.platform == 'win32':
 python = r'c:\Python24\python.exe'
 else:
Modified: branches/transforms/examples/clippedline.py
===================================================================
--- branches/transforms/examples/clippedline.py	2007年09月10日 17:40:47 UTC (rev 3823)
+++ branches/transforms/examples/clippedline.py	2007年09月10日 17:45:15 UTC (rev 3824)
@@ -4,7 +4,7 @@
 """
 
 from matplotlib.lines import Line2D
-import matplotlib.numerix as nx
+import numpy as npy
 from pylab import figure, show
 
 class ClippedLine(Line2D):
@@ -19,13 +19,13 @@
 
 def set_data(self, *args, **kwargs):
 Line2D.set_data(self, *args, **kwargs)
- self.xorig = nx.array(self._x)
- self.yorig = nx.array(self._y)
+ self.xorig = npy.array(self._x)
+ self.yorig = npy.array(self._y)
 
 def draw(self, renderer):
 xlim = self.ax.get_xlim()
 
- ind0, ind1 = nx.searchsorted(self.xorig, xlim)
+ ind0, ind1 = npy.searchsorted(self.xorig, xlim)
 self._x = self.xorig[ind0:ind1]
 self._y = self.yorig[ind0:ind1]
 N = len(self._x)
@@ -43,8 +43,8 @@
 fig = figure()
 ax = fig.add_subplot(111, autoscale_on=False)
 
-t = nx.arange(0.0, 100.0, 0.01)
-s = nx.sin(2*nx.pi*t)
+t = npy.arange(0.0, 100.0, 0.01)
+s = npy.sin(2*npy.pi*t)
 line = ClippedLine(ax, t, s, color='g', ls='-', lw=2)
 ax.add_line(line)
 ax.set_xlim(10,30)
Modified: branches/transforms/examples/collections_demo.py
===================================================================
--- branches/transforms/examples/collections_demo.py	2007年09月10日 17:40:47 UTC (rev 3823)
+++ branches/transforms/examples/collections_demo.py	2007年09月10日 17:45:15 UTC (rev 3824)
@@ -17,10 +17,10 @@
 
 '''
 
-import pylab as P
+import matplotlib.pyplot as P
 from matplotlib import collections, axes, transforms
 from matplotlib.colors import colorConverter
-import matplotlib.numerix as N
+import numpy as N
 
 nverts = 50
 npts = 100
@@ -33,8 +33,8 @@
 spiral = zip(xx,yy)
 
 # Make some offsets
-xo = P.randn(npts)
-yo = P.randn(npts)
+xo = N.random.randn(npts)
+yo = N.random.randn(npts)
 xyo = zip(xo, yo)
 
 # Make a list of colors cycling through the rgbcmyk series.
@@ -90,7 +90,7 @@
 a = fig.add_subplot(2,2,3)
 
 col = collections.RegularPolyCollection(fig.dpi, 7,
- sizes = P.fabs(xx)*10, offsets=xyo,
+ sizes = N.fabs(xx)*10, offsets=xyo,
 transOffset=a.transData)
 a.add_collection(col, autolim=True)
 trans = transforms.scale_transform(fig.dpi/transforms.Value(72.),
@@ -111,12 +111,12 @@
 ncurves = 20
 offs = (0.1, 0.0)
 
-yy = P.linspace(0, 2*N.pi, nverts)
-ym = P.amax(yy)
+yy = N.linspace(0, 2*N.pi, nverts)
+ym = N.amax(yy)
 xx = (0.2 + (ym-yy)/ym)**2 * N.cos(yy-0.4) * 0.5
 segs = []
 for i in range(ncurves):
- xxx = xx + 0.02*P.randn(nverts)
+ xxx = xx + 0.02*N.random.randn(nverts)
 curve = zip(xxx, yy*100)
 segs.append(curve)
 
Modified: branches/transforms/examples/color_by_yvalue.py
===================================================================
--- branches/transforms/examples/color_by_yvalue.py	2007年09月10日 17:40:47 UTC (rev 3823)
+++ branches/transforms/examples/color_by_yvalue.py	2007年09月10日 17:45:15 UTC (rev 3824)
@@ -1,7 +1,7 @@
 # use masked arrays to plot a line with different colors by y-value
-import matplotlib.numerix.ma as ma
-from matplotlib.numerix import logical_or
-from pylab import plot, show, arange, sin, pi
+import matplotlib.numerix.npyma as ma
+from numpy import logical_or, arange, sin, pi
+from matplotlib.pyplot import plot, show
 
 t = arange(0.0, 2.0, 0.01)
 s = sin(2*pi*t)
Modified: branches/transforms/examples/contourf_demo.py
===================================================================
--- branches/transforms/examples/contourf_demo.py	2007年09月10日 17:40:47 UTC (rev 3823)
+++ branches/transforms/examples/contourf_demo.py	2007年09月10日 17:45:15 UTC (rev 3824)
@@ -1,6 +1,6 @@
 #!/usr/bin/env python
 from pylab import *
-import matplotlib.numerix.ma as ma
+import matplotlib.numerix.npyma as ma
 origin = 'lower'
 #origin = 'upper'
 
Modified: branches/transforms/examples/data_helper.py
===================================================================
--- branches/transforms/examples/data_helper.py	2007年09月10日 17:40:47 UTC (rev 3823)
+++ branches/transforms/examples/data_helper.py	2007年09月10日 17:45:15 UTC (rev 3824)
@@ -1,7 +1,8 @@
 #!/usr/bin/env python
 # Some functions to load a return data for the plot demos
 
-from matplotlib.numerix import fromstring, argsort, take, array, resize
+from numpy import fromstring, argsort, take, array, resize
+
 def get_two_stock_data():
 """
 load stock time and price data for two stocks The return values
Modified: branches/transforms/examples/dynamic_demo_wx.py
===================================================================
--- branches/transforms/examples/dynamic_demo_wx.py	2007年09月10日 17:40:47 UTC (rev 3823)
+++ branches/transforms/examples/dynamic_demo_wx.py	2007年09月10日 17:45:15 UTC (rev 3824)
@@ -63,7 +63,7 @@
 
 from matplotlib.figure import Figure
 from matplotlib.axes import Subplot
-import matplotlib.numerix as numpy
+import numpy
 from wx import *
 
 
Modified: branches/transforms/examples/dynamic_image_wxagg.py
===================================================================
--- branches/transforms/examples/dynamic_image_wxagg.py	2007年09月10日 17:40:47 UTC (rev 3823)
+++ branches/transforms/examples/dynamic_image_wxagg.py	2007年09月10日 17:45:15 UTC (rev 3824)
@@ -12,26 +12,13 @@
 import matplotlib
 matplotlib.use('WXAgg')
 
-# jdh: you need to control Numeric vs numarray with numerix, otherwise
-# matplotlib may be using numeric under the hood and while you are
-# using numarray and this isn't efficient. Also, if you use
-# numerix=numarray, it is important to compile matplotlib for numarray
-# by setting NUMERIX = 'numarray' in setup.py before building
 from matplotlib import rcParams
-##rcParams['numerix'] = 'numarray'
-
-
-# jdh: you can import cm directly, you don't need to go via
-# pylab
 import matplotlib.cm as cm
 
 from matplotlib.backends.backend_wxagg import Toolbar, FigureCanvasWxAgg
 
-# jdh: you don't need a figure manager in the GUI - this class was
-# designed for the pylab interface
-
 from matplotlib.figure import Figure
-import matplotlib.numerix as numerix
+import numpy as npy
 import wx
 
 
@@ -75,12 +62,12 @@
 # jdh you can add a subplot directly from the fig rather than
 # the fig manager
 a = self.fig.add_subplot(111)
- self.x = numerix.arange(120.0)*2*numerix.pi/120.0
+ self.x = npy.arange(120.0)*2*npy.pi/120.0
 self.x.resize((100,120))
- self.y = numerix.arange(100.0)*2*numerix.pi/100.0
+ self.y = npy.arange(100.0)*2*npy.pi/100.0
 self.y.resize((120,100))
- self.y = numerix.transpose(self.y)
- z = numerix.sin(self.x) + numerix.cos(self.y)
+ self.y = npy.transpose(self.y)
+ z = npy.sin(self.x) + npy.cos(self.y)
 self.im = a.imshow( z, cmap=cm.jet)#, interpolation='nearest')
 
 def GetToolBar(self):
@@ -89,9 +76,9 @@
 return self.toolbar
 
 def onTimer(self, evt):
- self.x += numerix.pi/15
- self.y += numerix.pi/20
- z = numerix.sin(self.x) + numerix.cos(self.y)
+ self.x += npy.pi/15
+ self.y += npy.pi/20
+ z = npy.sin(self.x) + npy.cos(self.y)
 self.im.set_array(z)
 self.canvas.draw()
 #self.canvas.gui_repaint() # jdh wxagg_draw calls this already
Modified: branches/transforms/examples/dynamic_image_wxagg2.py
===================================================================
--- branches/transforms/examples/dynamic_image_wxagg2.py	2007年09月10日 17:40:47 UTC (rev 3823)
+++ branches/transforms/examples/dynamic_image_wxagg2.py	2007年09月10日 17:45:15 UTC (rev 3824)
@@ -12,24 +12,14 @@
 import matplotlib
 matplotlib.use('WXAgg')
 
-# jdh: you need to control Numeric vs numarray with numerix, otherwise
-# matplotlib may be using numeric under the hood and while you are
-# using numarray and this isn't efficient. Also, if you use
-# numerix=numarray, it is important to compile matplotlib for numarray
-# by setting NUMERIX = 'numarray' in setup.py before building
 from matplotlib import rcParams
 import numpy as npy
 
-# jdh: you can import cm directly, you don't need to go via
-# pylab
 import matplotlib.cm as cm
 
 from matplotlib.backends.backend_wxagg import FigureCanvasWxAgg
 from matplotlib.backends.backend_wx import NavigationToolbar2Wx
 
-# jdh: you don't need a figure manager in the GUI - this class was
-# designed for the pylab interface
-
 from matplotlib.figure import Figure
 from wx import *
 
Modified: branches/transforms/examples/embedding_in_gtk.py
===================================================================
--- branches/transforms/examples/embedding_in_gtk.py	2007年09月10日 17:40:47 UTC (rev 3823)
+++ branches/transforms/examples/embedding_in_gtk.py	2007年09月10日 17:45:15 UTC (rev 3824)
@@ -8,7 +8,7 @@
 
 from matplotlib.axes import Subplot
 from matplotlib.figure import Figure
-from matplotlib.numerix import arange, sin, pi
+from numpy import arange, sin, pi
 
 # uncomment to select /GTK/GTKAgg/GTKCairo
 from matplotlib.backends.backend_gtk import FigureCanvasGTK as FigureCanvas
Modified: branches/transforms/examples/embedding_in_gtk2.py
===================================================================
--- branches/transforms/examples/embedding_in_gtk2.py	2007年09月10日 17:40:47 UTC (rev 3823)
+++ branches/transforms/examples/embedding_in_gtk2.py	2007年09月10日 17:45:15 UTC (rev 3824)
@@ -7,7 +7,7 @@
 
 from matplotlib.axes import Subplot
 from matplotlib.figure import Figure
-from matplotlib.numerix import arange, sin, pi
+from numpy import arange, sin, pi
 
 # uncomment to select /GTK/GTKAgg/GTKCairo
 from matplotlib.backends.backend_gtk import FigureCanvasGTK as FigureCanvas
Modified: branches/transforms/examples/embedding_in_gtk3.py
===================================================================
--- branches/transforms/examples/embedding_in_gtk3.py	2007年09月10日 17:40:47 UTC (rev 3823)
+++ branches/transforms/examples/embedding_in_gtk3.py	2007年09月10日 17:45:15 UTC (rev 3824)
@@ -7,7 +7,7 @@
 
 from matplotlib.axes import Subplot
 from matplotlib.figure import Figure
-from matplotlib.numerix import arange, sin, pi
+from numpy import arange, sin, pi
 
 # uncomment to select /GTK/GTKAgg/GTKCairo
 #from matplotlib.backends.backend_gtk import FigureCanvasGTK as FigureCanvas
Modified: branches/transforms/examples/embedding_in_qt.py
===================================================================
--- branches/transforms/examples/embedding_in_qt.py	2007年09月10日 17:40:47 UTC (rev 3823)
+++ branches/transforms/examples/embedding_in_qt.py	2007年09月10日 17:45:15 UTC (rev 3824)
@@ -11,7 +11,7 @@
 import sys, os, random
 from qt import *
 
-from matplotlib.numerix import arange, sin, pi
+from numpy import arange, sin, pi
 from matplotlib.backends.backend_qtagg import FigureCanvasQTAgg as FigureCanvas
 from matplotlib.figure import Figure
 
Modified: branches/transforms/examples/embedding_in_qt4.py
===================================================================
--- branches/transforms/examples/embedding_in_qt4.py	2007年09月10日 17:40:47 UTC (rev 3823)
+++ branches/transforms/examples/embedding_in_qt4.py	2007年09月10日 17:45:15 UTC (rev 3824)
@@ -12,7 +12,7 @@
 import sys, os, random
 from PyQt4 import QtGui, QtCore
 
-from matplotlib.numerix import arange, sin, pi
+from numpy import arange, sin, pi
 from matplotlib.backends.backend_qt4agg import FigureCanvasQTAgg as FigureCanvas
 from matplotlib.figure import Figure
 
Modified: branches/transforms/examples/embedding_in_tk.py
===================================================================
--- branches/transforms/examples/embedding_in_tk.py	2007年09月10日 17:40:47 UTC (rev 3823)
+++ branches/transforms/examples/embedding_in_tk.py	2007年09月10日 17:45:15 UTC (rev 3824)
@@ -2,7 +2,7 @@
 import matplotlib
 matplotlib.use('TkAgg')
 
-from matplotlib.numerix import arange, sin, pi
+from numpy import arange, sin, pi
 from matplotlib.axes import Subplot
 from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg, NavigationToolbar2TkAgg
 from matplotlib.figure import Figure
Modified: branches/transforms/examples/embedding_in_tk2.py
===================================================================
--- branches/transforms/examples/embedding_in_tk2.py	2007年09月10日 17:40:47 UTC (rev 3823)
+++ branches/transforms/examples/embedding_in_tk2.py	2007年09月10日 17:45:15 UTC (rev 3824)
@@ -2,7 +2,7 @@
 import matplotlib
 matplotlib.use('TkAgg')
 
-from matplotlib.numerix import arange, sin, pi
+from numpy import arange, sin, pi
 from matplotlib.axes import Subplot
 from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg, NavigationToolbar2TkAgg
 from matplotlib.figure import Figure
Modified: branches/transforms/examples/embedding_in_wx.py
===================================================================
--- branches/transforms/examples/embedding_in_wx.py	2007年09月10日 17:40:47 UTC (rev 3823)
+++ branches/transforms/examples/embedding_in_wx.py	2007年09月10日 17:45:15 UTC (rev 3824)
@@ -44,7 +44,7 @@
 
 from matplotlib.figure import Figure
 from matplotlib.axes import Subplot
-import matplotlib.numerix as numpy
+import numpy
 from wx import *
 
 
Modified: branches/transforms/examples/embedding_in_wx2.py
===================================================================
--- branches/transforms/examples/embedding_in_wx2.py	2007年09月10日 17:40:47 UTC (rev 3823)
+++ branches/transforms/examples/embedding_in_wx2.py	2007年09月10日 17:45:15 UTC (rev 3824)
@@ -4,7 +4,7 @@
 toolbar - comment out the setA_toolbar line for no toolbar
 """
 
-from matplotlib.numerix import arange, sin, pi
+from numpy import arange, sin, pi
 
 import matplotlib
 
Modified: branches/transforms/examples/embedding_in_wx3.py
===================================================================
--- branches/transforms/examples/embedding_in_wx3.py	2007年09月10日 17:40:47 UTC (rev 3823)
+++ branches/transforms/examples/embedding_in_wx3.py	2007年09月10日 17:45:15 UTC (rev 3824)
@@ -25,8 +25,6 @@
 from matplotlib.backends.backend_wxagg import Toolbar, FigureCanvasWxAgg
 from matplotlib.figure import Figure
 import numpy as npy
-import matplotlib.numerix.mlab as mlab
-from matplotlib.mlab import meshgrid
 
 from wx import *
 from wx.xrc import *
@@ -61,11 +59,11 @@
 
 x = npy.arange(120.0)*2*npy.pi/60.0
 y = npy.arange(100.0)*2*npy.pi/50.0
- self.x, self.y = meshgrid(x, y)
+ self.x, self.y = npy.meshgrid(x, y)
 z = npy.sin(self.x) + npy.cos(self.y)
 self.im = a.imshow( z, cmap=cm.jet)#, interpolation='nearest')
 
- zmax = mlab.max(mlab.max(z))-ERR_TOL
+ zmax = npy.amax(z) - ERR_TOL
 ymax_i, xmax_i = npy.nonzero(z >= zmax)
 if self.im.origin == 'upper':
 ymax_i = z.shape[0]-ymax_i
@@ -84,7 +82,7 @@
 z = npy.sin(self.x) + npy.cos(self.y)
 self.im.set_array(z)
 
- zmax = mlab.max(mlab.max(z))-ERR_TOL
+ zmax = npy.amax(z) - ERR_TOL
 ymax_i, xmax_i = npy.nonzero(z >= zmax)
 if self.im.origin == 'upper':
 ymax_i = z.shape[0]-ymax_i
Modified: branches/transforms/examples/embedding_in_wx4.py
===================================================================
--- branches/transforms/examples/embedding_in_wx4.py	2007年09月10日 17:40:47 UTC (rev 3823)
+++ branches/transforms/examples/embedding_in_wx4.py	2007年09月10日 17:45:15 UTC (rev 3824)
@@ -4,7 +4,7 @@
 toolbar
 """
 
-from matplotlib.numerix import arange, sin, pi
+from numpy import arange, sin, pi
 
 import matplotlib
 
@@ -19,7 +19,7 @@
 
 from matplotlib.backends.backend_wx import _load_bitmap
 from matplotlib.figure import Figure
-from matplotlib.numerix.mlab import rand
+from numpy.random import rand
 
 from wx import *
 
Deleted: branches/transforms/examples/gdtest.py
===================================================================
--- branches/transforms/examples/gdtest.py	2007年09月10日 17:40:47 UTC (rev 3823)
+++ branches/transforms/examples/gdtest.py	2007年09月10日 17:45:15 UTC (rev 3824)
@@ -1,34 +0,0 @@
-#!/usr/bin/env python
-import matplotlib
-matplotlib.use('GD')
-from pylab import *
-
-def f(t):
- s1 = cos(2*pi*t)
- e1 = exp(-t)
- return multiply(s1,e1)
-
-t1 = arange(0.0, 5.0, .1)
-t2 = arange(0.0, 5.0, 0.02)
-t3 = arange(0.0, 2.0, 0.01)
-
-
-if 1:
- subplot(211)
- l = plot(t1, f(t1), 'k-^')
- setp(l, 'markerfacecolor', 'r')
- xlim(0,5)
- title('A tale of 2 subplots', fontsize=12)
- ylabel('Signal 1', fontsize=10)
-
- subplot(212)
- l = plot(t1, f(t1), 'k->')
- xlim(0,5)
- ylabel('Signal 2', fontsize=10)
- xlabel('time (s)', fontsize=10, fontname='Courier')
-
-ax = gca()
-
-
-#savefig('gdtest', dpi=150)
-show()
Modified: branches/transforms/examples/gtk_spreadsheet.py
===================================================================
--- branches/transforms/examples/gtk_spreadsheet.py	2007年09月10日 17:40:47 UTC (rev 3823)
+++ branches/transforms/examples/gtk_spreadsheet.py	2007年09月10日 17:45:15 UTC (rev 3824)
@@ -14,15 +14,13 @@
 matplotlib.use('GTKAgg') # or 'GTK'
 from matplotlib.backends.backend_gtk import FigureCanvasGTK as FigureCanvas
 
-#from matplotlib.numerix import rand
-from matplotlib.numerix.random_array import random
+from numpy.random import random
 from matplotlib.figure import Figure
 
 
 class DataManager(gtk.Window):
 numRows, numCols = 20,10
 
- #data = rand(numRows, numCols)
 data = random((numRows, numCols))
 
 def __init__(self):
Modified: branches/transforms/examples/histogram_demo_canvasagg.py
===================================================================
--- branches/transforms/examples/histogram_demo_canvasagg.py	2007年09月10日 17:40:47 UTC (rev 3823)
+++ branches/transforms/examples/histogram_demo_canvasagg.py	2007年09月10日 17:45:15 UTC (rev 3824)
@@ -13,7 +13,8 @@
 from matplotlib.figure import Figure
 from matplotlib.axes import Subplot
 from matplotlib.mlab import normpdf
-from matplotlib.numerix.mlab import randn
+from numpy.random import randn
+import numpy
 
 fig = Figure(figsize=(5,4), dpi=100)
 ax = fig.add_subplot(111)
@@ -42,14 +43,14 @@
 
 s = canvas.tostring_rgb() # save this and convert to bitmap as needed
 
-# get the figure dimensions for creating bitmaps or numeric arrays,
+# get the figure dimensions for creating bitmaps or numpy arrays,
 # etc.
 l,b,w,h = fig.bbox.get_bounds()
 w, h = int(w), int(h)
 
 if 0:
- # convert to a Numeric array
- X = fromstring(s, UInt8)
+ # convert to a numpy array
+ X = numpy.fromstring(s, numpy.uint8)
 X.shape = h, w, 3
 
 if 0:
Deleted: branches/transforms/examples/image_demo_na.py
===================================================================
--- branches/transforms/examples/image_demo_na.py	2007年09月10日 17:40:47 UTC (rev 3823)
+++ branches/transforms/examples/image_demo_na.py	2007年09月10日 17:45:15 UTC (rev 3824)
@@ -1,40 +0,0 @@
-#!/usr/bin/env python
-from matplotlib import rcParams
-rcParams['numerix'] = 'numarray'
-
-from pylab import *
-
-
-def bivariate_normal(X, Y, sigmax=1.0, sigmay=1.0,
- mux=0.0, muy=0.0, sigmaxy=0.0):
- """
- Bivariate gaussan distribution for equal shape X, Y
-
- http://mathworld.wolfram.com/BivariateNormalDistribution.html
- """
- Xmu = X-mux
- Ymu = Y-muy
-
- rho = sigmaxy/(sigmax*sigmay)
- z = (1.0/sigmax**2)*Xmu**2 + (1.0/sigmay)*Ymu**2 - (2*rho/(sigmax*sigmay))*Xmu*Ymu
- return 1.0/(2*pi*sigmax*sigmay*(1-rho**2)) * exp( -1/(2*(1-rho**2))*z)
-
-
-delta = 0.025
-x = arange(-3.0, 3.0, delta)
-y = arange(-3.0, 3.0, delta)
-X,Y = meshgrid(x, y)
-Z1 = bivariate_normal(X, Y, 1.0, 1.0, 0.0, 0.0)
-Z2 = bivariate_normal(X, Y, 1.5, 0.5, 1, 1)
-
-# difference of Gaussians
-im = imshow(Z2-Z1)
-
-# set the interpolation method: 'nearest', 'bilinear', 'bicubic' and much more
-im.set_interpolation('bilinear')
-
-
-axis('off')
-#savefig('test')
-show()
-
Modified: branches/transforms/examples/image_masked.py
===================================================================
--- branches/transforms/examples/image_masked.py	2007年09月10日 17:40:47 UTC (rev 3823)
+++ branches/transforms/examples/image_masked.py	2007年09月10日 17:45:15 UTC (rev 3824)
@@ -4,7 +4,7 @@
 '''
 
 from pylab import *
-import matplotlib.numerix.ma as ma
+import matplotlib.numerix.npyma as ma
 import matplotlib.colors as colors
 
 delta = 0.025
Modified: branches/transforms/examples/mathtext_wx.py
===================================================================
--- branches/transforms/examples/mathtext_wx.py	2007年09月10日 17:40:47 UTC (rev 3823)
+++ branches/transforms/examples/mathtext_wx.py	2007年09月10日 17:45:15 UTC (rev 3824)
@@ -5,7 +5,7 @@
 
 import matplotlib
 matplotlib.use("WxAgg")
-from matplotlib.numerix import arange, sin, pi, cos, log
+from numpy import arange, sin, pi, cos, log
 from matplotlib.backends.backend_wxagg import FigureCanvasWxAgg as FigureCanvas
 from matplotlib.backends.backend_wx import NavigationToolbar2Wx
 from matplotlib.figure import Figure
@@ -42,14 +42,14 @@
 self.figure = Figure()
 self.axes = self.figure.add_subplot(111)
 self.change_plot(0)
- 
+
 self.canvas = FigureCanvas(self, -1, self.figure)
 
 self.sizer = wx.BoxSizer(wx.VERTICAL)
 self.add_buttonbar()
 self.sizer.Add(self.canvas, 1, wx.LEFT | wx.TOP | wx.GROW)
 self.add_toolbar() # comment this out for no toolbar
- 
+
 menuBar = wx.MenuBar()
 
 # File Menu
@@ -104,21 +104,21 @@
 
 def OnChangePlot(self, event):
 self.change_plot(event.GetId() - 1000)
- 
+
 def change_plot(self, plot_number):
 t = arange(1.0,3.0,0.01)
 s = functions[plot_number][1](t)
 self.axes.clear()
 self.axes.plot(t, s)
 self.Refresh()
- 
+
 class MyApp(wx.App):
 def OnInit(self):
 frame = CanvasFrame(None, "wxPython mathtext demo app")
 self.SetTopWindow(frame)
 frame.Show(True)
 return True
- 
+
 app = MyApp()
 app.MainLoop()
 
Modified: branches/transforms/examples/mpl_with_glade.py
===================================================================
--- branches/transforms/examples/mpl_with_glade.py	2007年09月10日 17:40:47 UTC (rev 3823)
+++ branches/transforms/examples/mpl_with_glade.py	2007年09月10日 17:45:15 UTC (rev 3824)
@@ -8,7 +8,7 @@
 from matplotlib.backends.backend_gtkagg import NavigationToolbar2GTKAgg as NavigationToolbar
 from matplotlib.widgets import SpanSelector
 
-from matplotlib.numerix import arange, sin, pi
+from numpy import arange, sin, pi
 import gtk
 import gtk.glade
 
Modified: branches/transforms/examples/multi_image.py
===================================================================
--- branches/transforms/examples/multi_image.py	2007年09月10日 17:40:47 UTC (rev 3823)
+++ branches/transforms/examples/multi_image.py	2007年09月10日 17:45:15 UTC (rev 3824)
@@ -5,19 +5,20 @@
 It also illustrates colorbar tick labelling with a multiplier.
 '''
 
-import pylab
+from matplotlib.pyplot import figure, show, sci
 from matplotlib import cm, colors
 from matplotlib.font_manager import FontProperties
-from matplotlib.numerix.mlab import amin, amax
+from numpy import amin, amax, ravel
+from numpy.random import rand
 
 Nr = 3
 Nc = 2
 
-fig = pylab.gcf()
+fig = figure()
 cmap = cm.cool
 
 figtitle = 'Multiple images'
-t = pylab.gcf().text(0.5, 0.95, figtitle,
+t = fig.text(0.5, 0.95, figtitle,
 horizontalalignment='center',
 fontproperties=FontProperties(size=16))
 
@@ -37,8 +38,8 @@
 a.set_xticklabels([])
 # Make some fake data with a range that varies
 # somewhat from one plot to the next.
- data =((1+i+j)/10.0)*pylab.rand(10,20)*1e-6
- dd = pylab.ravel(data)
+ data =((1+i+j)/10.0)*rand(10,20)*1e-6
+ dd = ravel(data)
 # Manually find the min and max of all colors for
 # use in setting the color scale.
 vmin = min(vmin, amin(dd))
@@ -60,12 +61,13 @@
 
 # We need the following only if we want to run this
 # script interactively and be able to change the colormap.
-pylab.sci(images[0])
 
-pylab.show()
+sci(images[0])
 
+show()
 
 
 
 
 
+
Modified: branches/transforms/examples/pcolor_nonuniform.py
===================================================================
--- branches/transforms/examples/pcolor_nonuniform.py	2007年09月10日 17:40:47 UTC (rev 3823)
+++ branches/transforms/examples/pcolor_nonuniform.py	2007年09月10日 17:45:15 UTC (rev 3824)
@@ -1,11 +1,11 @@
-from pylab import figure, show
-import matplotlib.numerix as nx
+from matplotlib.pyplot import figure, show
+import numpy as npy
 from matplotlib.image import NonUniformImage
 
-x = nx.arange(-4, 4, 0.005)
-y = nx.arange(-4, 4, 0.005)
+x = npy.arange(-4, 4, 0.005)
+y = npy.arange(-4, 4, 0.005)
 print 'Size %d points' % (len(x) * len(y))
-z = nx.sqrt(x[nx.NewAxis,:]**2 + y[:,nx.NewAxis]**2)
+z = npy.sqrt(x[npy.newaxis,:]**2 + y[:,npy.newaxis]**2)
 
 fig = figure()
 ax = fig.add_subplot(111)
Modified: branches/transforms/examples/polar_bar.py
===================================================================
--- branches/transforms/examples/polar_bar.py	2007年09月10日 17:40:47 UTC (rev 3823)
+++ branches/transforms/examples/polar_bar.py	2007年09月10日 17:45:15 UTC (rev 3824)
@@ -1,9 +1,8 @@
 #!/usr/bin/env python
 
-import matplotlib.numerix as nx
-from matplotlib.mlab import linspace
+import numpy as npy
 import matplotlib.cm as cm
-from pylab import figure, show, rc
+from matplotlib.pyplot import figure, show, rc
 
 
 # force square figure and square axes looks better for polar, IMO
@@ -11,9 +10,9 @@
 ax = fig.add_axes([0.1, 0.1, 0.8, 0.8], polar=True)
 
 N = 20
-theta = nx.arange(0.0, 2*nx.pi, 2*nx.pi/N)
-radii = 10*nx.mlab.rand(N)
-width = nx.pi/4*nx.mlab.rand(N)
+theta = npy.arange(0.0, 2*npy.pi, 2*npy.pi/N)
+radii = 10*npy.random.rand(N)
+width = npy.pi/4*npy.random.rand(N)
 bars = ax.bar(theta, radii, width=width, bottom=0.1)
 for r,bar in zip(radii, bars):
 bar.set_facecolor( cm.jet(r/10.))
Modified: branches/transforms/examples/polar_demo.py
===================================================================
--- branches/transforms/examples/polar_demo.py	2007年09月10日 17:40:47 UTC (rev 3823)
+++ branches/transforms/examples/polar_demo.py	2007年09月10日 17:45:15 UTC (rev 3824)
@@ -39,8 +39,8 @@
 # See the pylab rgrids and thetagrids functions for
 # information on how to customize the grid locations and labels
 
-import matplotlib.numerix as nx
-from pylab import figure, show, rc
+import numpy as npy
+from matplotlib.pyplot import figure, show, rc
 
 # radar green, solid grid lines
 rc('grid', color='#316931', linewidth=1, linestyle='-')
@@ -51,8 +51,8 @@
 fig = figure(figsize=(8,8))
 ax = fig.add_axes([0.1, 0.1, 0.8, 0.8], polar=True, axisbg='#d5de9c')
 
-r = nx.arange(0, 3.0, 0.01)
-theta = 2*nx.pi*r
+r = npy.arange(0, 3.0, 0.01)
+theta = 2*npy.pi*r
 ax.plot(theta, r, color='#ee8d18', lw=3)
 ax.set_rmax(2.0)
 
Modified: branches/transforms/examples/polar_legend.py
===================================================================
--- branches/transforms/examples/polar_legend.py	2007年09月10日 17:40:47 UTC (rev 3823)
+++ branches/transforms/examples/polar_legend.py	2007年09月10日 17:45:15 UTC (rev 3824)
@@ -1,7 +1,7 @@
 #!/usr/bin/env python
 
-import matplotlib.numerix as nx
-from pylab import figure, show, rc
+import numpy as npy
+from matplotlib.pyplot import figure, show, rc
 
 # radar green, solid grid lines
 rc('grid', color='#316931', linewidth=1, linestyle='-')
@@ -12,8 +12,8 @@
 fig = figure(figsize=(8,8))
 ax = fig.add_axes([0.1, 0.1, 0.8, 0.8], polar=True, axisbg='#d5de9c')
 
-r = nx.arange(0, 3.0, 0.01)
-theta = 2*nx.pi*r
+r = npy.arange(0, 3.0, 0.01)
+theta = 2*npy.pi*r
 ax.plot(theta, r, color='#ee8d18', lw=3, label='a line')
 ax.plot(0.5*theta, r, color='blue', ls='--', lw=3, label='another line')
 ax.legend()
Modified: branches/transforms/examples/poly_editor.py
===================================================================
--- branches/transforms/examples/poly_editor.py	2007年09月10日 17:40:47 UTC (rev 3823)
+++ branches/transforms/examples/poly_editor.py	2007年09月10日 17:45:15 UTC (rev 3824)
@@ -5,8 +5,7 @@
 """
 from matplotlib.artist import Artist
 from matplotlib.patches import Polygon, CirclePolygon
-from matplotlib.numerix import sqrt, nonzero, equal, asarray, dot, Float
-from matplotlib.numerix.mlab import amin
+from numpy import sqrt, nonzero, equal, asarray, dot, amin
 from matplotlib.mlab import dist_point_to_segment
 
 
Modified: branches/transforms/examples/printing_in_wx.py
===================================================================
--- branches/transforms/examples/printing_in_wx.py	2007年09月10日 17:40:47 UTC (rev 3823)
+++ branches/transforms/examples/printing_in_wx.py	2007年09月10日 17:45:15 UTC (rev 3824)
@@ -39,7 +39,7 @@
 from matplotlib.backends.backend_wxagg import FigureCanvasWxAgg as FigCanvas
 
 from matplotlib.figure import Figure
-import matplotlib.numerix as numpy
+import numpy
 
 class PlotFrame(wx.Frame):
 help_msg=""" Menus for
Modified: branches/transforms/examples/pythonic_matplotlib.py
===================================================================
--- branches/transforms/examples/pythonic_matplotlib.py	2007年09月10日 17:40:47 UTC (rev 3823)
+++ branches/transforms/examples/pythonic_matplotlib.py	2007年09月10日 17:45:15 UTC (rev 3824)
@@ -54,7 +54,7 @@
 
 
 from pylab import figure, close, axes, subplot, show
-from matplotlib.numerix import arange, sin, pi
+from numpy import arange, sin, pi
 
 t = arange(0.0, 1.0, 0.01)
 
Modified: branches/transforms/examples/rc_traits.py
===================================================================
--- branches/transforms/examples/rc_traits.py	2007年09月10日 17:40:47 UTC (rev 3823)
+++ branches/transforms/examples/rc_traits.py	2007年09月10日 17:45:15 UTC (rev 3824)
@@ -128,8 +128,8 @@
 antialiased = flexible_true_trait
 
 timezones = 'UTC', 'US/Central', 'ES/Eastern' # fixme: and many more
-backends = ('GTKAgg', 'Cairo', 'FltkAgg', 'GD', 'GDK', 'GTK', 'Agg',
- 'GTKCairo', 'Paint', 'PS', 'SVG', 'Template', 'TkAgg',
+backends = ('GTKAgg', 'Cairo', 'FltkAgg', 'GDK', 'GTK', 'Agg',
+ 'GTKCairo', 'PS', 'SVG', 'Template', 'TkAgg',
 'WX')
 
 class RC(traits.HasTraits):
Modified: branches/transforms/examples/scatter_masked.py
===================================================================
--- branches/transforms/examples/scatter_masked.py	2007年09月10日 17:40:47 UTC (rev 3823)
+++ branches/transforms/examples/scatter_masked.py	2007年09月10日 17:45:15 UTC (rev 3824)
@@ -1,6 +1,6 @@
 #!/usr/bin/env python
 from pylab import *
-import matplotlib.numerix.ma as ma
+import matplotlib.numerix.npyma as ma
 
 N = 100
 r0 = 0.6
Modified: branches/transforms/examples/strip_chart_demo.py
===================================================================
--- branches/transforms/examples/strip_chart_demo.py	2007年09月10日 17:40:47 UTC (rev 3823)
+++ branches/transforms/examples/strip_chart_demo.py	2007年09月10日 17:45:15 UTC (rev 3824)
@@ -12,7 +12,7 @@
 import gobject, gtk
 import matplotlib
 matplotlib.use('GTKAgg')
-import matplotlib.numerix as nx
+import numpy as npy
 from matplotlib.lines import Line2D
 
 
@@ -36,9 +36,9 @@
 
 def emitter(self, p=0.01):
 'return a random value with probability p, else 0'
- v = nx.mlab.rand(1)
+ v = npy.random.rand(1)
 if v>p: return 0.
- else: return nx.mlab.rand(1)
+ else: return npy.random.rand(1)
 
 def update(self, *args):
 if self.background is None: return True
Modified: branches/transforms/examples/tex_demo.py
===================================================================
--- branches/transforms/examples/tex_demo.py	2007年09月10日 17:40:47 UTC (rev 3823)
+++ branches/transforms/examples/tex_demo.py	2007年09月10日 17:45:15 UTC (rev 3824)
@@ -11,8 +11,8 @@
 
 """
 from matplotlib import rc
-from matplotlib.numerix import arange, cos, pi
-from pylab import figure, axes, plot, xlabel, ylabel, title, \
+from numpy import arange, cos, pi
+from matplotlib.pyplot import figure, axes, plot, xlabel, ylabel, title, \
 grid, savefig, show
 
 
Modified: branches/transforms/examples/tex_unicode_demo.py
===================================================================
--- branches/transforms/examples/tex_unicode_demo.py	2007年09月10日 17:40:47 UTC (rev 3823)
+++ branches/transforms/examples/tex_unicode_demo.py	2007年09月10日 17:45:15 UTC (rev 3824)
@@ -7,8 +7,8 @@
 from matplotlib import rcParams
 rcParams['text.usetex']=True
 rcParams['text.latex.unicode']=True
-from matplotlib.numerix import arange, cos, pi
-from pylab import figure, axes, plot, xlabel, ylabel, title, \
+from numpy import arange, cos, pi
+from matplotlib.pyplot import figure, axes, plot, xlabel, ylabel, title, \
 grid, savefig, show
 
 figure(1)
Modified: branches/transforms/examples/vline_demo.py
===================================================================
--- branches/transforms/examples/vline_demo.py	2007年09月10日 17:40:47 UTC (rev 3823)
+++ branches/transforms/examples/vline_demo.py	2007年09月10日 17:45:15 UTC (rev 3824)
@@ -1,17 +1,17 @@
 #!/usr/bin/env python
-from pylab import *
-from matplotlib.numerix import sin, exp, multiply, absolute, pi
-from matplotlib.numerix.random_array import normal
+from matplotlib.pyplot import *
+from numpy import sin, exp, absolute, pi, arange
+from numpy.random import normal
 
 def f(t):
 s1 = sin(2*pi*t)
 e1 = exp(-t)
- return absolute(multiply(s1,e1))+.05
+ return absolute((s1*e1))+.05
 
 
 t = arange(0.0, 5.0, 0.1)
 s = f(t)
-nse = multiply(normal(0.0, 0.3, t.shape), s)
+nse = normal(0.0, 0.3, t.shape) * s
 
 plot(t, s+nse, 'b^')
 vlines(t, [0], s)
Modified: branches/transforms/examples/webapp_demo.py
===================================================================
--- branches/transforms/examples/webapp_demo.py	2007年09月10日 17:40:47 UTC (rev 3823)
+++ branches/transforms/examples/webapp_demo.py	2007年09月10日 17:45:15 UTC (rev 3824)
@@ -21,7 +21,7 @@
 from matplotlib.backends.backend_agg import FigureCanvasAgg
 from matplotlib.figure import Figure
 from matplotlib.cbook import iterable
-import matplotlib.numerix as nx
+import numpy as npy
 
 def make_fig():
 """
@@ -40,9 +40,9 @@
 line, = ax.plot([1,2,3], 'ro--', markersize=12, markerfacecolor='g')
 
 # make a translucent scatter collection
- x = nx.mlab.rand(100)
- y = nx.mlab.rand(100)
- area = nx.pi*(10 * nx.mlab.rand(100))**2 # 0 to 10 point radiuses
+ x = npy.random.rand(100)
+ y = npy.random.rand(100)
+ area = npy.pi*(10 * npy.random.rand(100))**2 # 0 to 10 point radiuses
 c = ax.scatter(x,y,area)
 c.set_alpha(0.5)
 
Modified: branches/transforms/examples/wxcursor_demo.py
===================================================================
--- branches/transforms/examples/wxcursor_demo.py	2007年09月10日 17:40:47 UTC (rev 3823)
+++ branches/transforms/examples/wxcursor_demo.py	2007年09月10日 17:45:15 UTC (rev 3824)
@@ -6,7 +6,7 @@
 from matplotlib.backends.backend_wxagg import FigureCanvasWxAgg as FigureCanvas
 from matplotlib.backends.backend_wx import NavigationToolbar2Wx
 from matplotlib.figure import Figure
-from matplotlib.numerix import arange, sin, pi
+from numpy import arange, sin, pi
 
 import wx
 
Modified: branches/transforms/lib/matplotlib/__init__.py
===================================================================
--- branches/transforms/lib/matplotlib/__init__.py	2007年09月10日 17:40:47 UTC (rev 3823)
+++ branches/transforms/lib/matplotlib/__init__.py	2007年09月10日 17:45:15 UTC (rev 3824)
@@ -530,16 +530,16 @@
 
 
 class RcParams(dict):
- 
+
 """A dictionary object including validation
- 
+
 validating functions are defined and associated with rc parameters in
 rcsetup.py
 """
- 
+
 validate = dict([ (key, converter) for key, (default, converter) in \
 defaultParams.iteritems() ])
- 
+
 def __setitem__(self, key, val):
 try:
 if key in _deprecated_map.keys():
@@ -620,7 +620,7 @@
 ret['datapath'] = get_data_path()
 
 verbose.report('loaded rc file %s'%fname)
- 
+
 return ret
 
 
Modified: branches/transforms/lib/matplotlib/axes.py
===================================================================
--- branches/transforms/lib/matplotlib/axes.py	2007年09月10日 17:40:47 UTC (rev 3823)
+++ branches/transforms/lib/matplotlib/axes.py	2007年09月10日 17:45:15 UTC (rev 3824)
@@ -1867,31 +1867,6 @@
 c =mcolors.colorConverter.to_rgba(c)
 self._cursorProps = lw, c
 
-
- def panx(self, numsteps):
- 'Pan the x axis numsteps (plus pan right, minus pan left)'
- self.xaxis.pan(numsteps)
- xmin, xmax = self.viewLim.intervalx().get_bounds()
- self._send_xlim_event()
-
- def pany(self, numsteps):
- 'Pan the x axis numsteps (plus pan up, minus pan down)'
- self.yaxis.pan(numsteps)
- self._send_ylim_event()
-
- def zoomx(self, numsteps):
- 'Zoom in on the x xaxis numsteps (plus for zoom in, minus for zoom out)'
- self.xaxis.zoom(numsteps)
- xmin, xmax = self.viewLim.intervalx().get_bounds()
- self._send_xlim_event()
-
- def zoomy(self, numsteps):
- 'Zoom in on the x xaxis numsteps (plus for zoom in, minus for zoom out)'
- self.yaxis.zoom(numsteps)
- self._send_ylim_event()
-
-
-
 def connect(self, s, func):
 """
 Register observers to be notified when certain events occur. Register
@@ -1913,6 +1888,7 @@
 def disconnect(self, cid):
 'disconnect from the Axes event.'
 raise DeprecationWarning('use the callbacks CallbackRegistry instance instead')
+
 def get_children(self):
 'return a list of child artists'
 children = []
@@ -5683,38 +5659,14 @@
 'ylabel not implemented'
 raise NotImplementedError('ylabel not defined for polar axes (yet)')
 
+ def set_xlim(self, xmin=None, xmax=None, emit=True, **kwargs):
+ 'xlim not implemented'
+ raise NotImplementedError('xlim not meaningful for polar axes')
 
- def set_xlim(self, xmin=None, xmax=None, emit=True):
- """
- set the xlimits
- ACCEPTS: len(2) sequence of floats
- """
- if xmax is None and iterable(xmin):
- xmin,xmax = xmin
+ def set_ylim(self, ymin=None, ymax=None, emit=True, **kwargs):
+ 'ylim not implemented'
+ raise NotImplementedError('ylim not meaningful for polar axes')
 
- old_xmin,old_xmax = self.get_xlim()
- if xmin is None: xmin = old_xmin
- if xmax is None: xmax = old_xmax
-
- self.viewLim.intervalx().set_bounds(xmin, xmax)
- if emit: self._send_xlim_event()
-
-
- def set_ylim(self, ymin=None, ymax=None, emit=True):
- """
- set the ylimits
- ACCEPTS: len(2) sequence of floats
- """
- if ymax is None and iterable(ymin):
- ymin,ymax = ymin
-
- old_ymin,old_ymax = self.get_ylim()
- if ymin is None: ymin = old_ymin
- if ymax is None: ymax = old_ymax
-
- self.viewLim.intervaly().set_bounds(ymin, ymax)
- if emit: self._send_ylim_event()
-
 def get_xscale(self):
 'return the xaxis scale string'
 return 'polar'
@@ -5765,10 +5717,9 @@
 """
 # this is some discarded code I was using to find the minimum positive
 # data point for some log scaling fixes. I realized there was a
-# cleaner way to do it, but am ke
-eping this around as an example for
+# cleaner way to do it, but am keeping this around as an example for
 # how to get the data out of the axes. Might want to make something
-# like this a method one day, or better yet make get_verts and Artist
+# like this a method one day, or better yet make get_verts an Artist
 # method
 
 minx, maxx = self.get_xlim()
Modified: branches/transforms/lib/matplotlib/backends/__init__.py
===================================================================
--- branches/transforms/lib/matplotlib/backends/__init__.py	2007年09月10日 17:40:47 UTC (rev 3823)
+++ branches/transforms/lib/matplotlib/backends/__init__.py	2007年09月10日 17:45:15 UTC (rev 3824)
@@ -7,7 +7,7 @@
 
 interactive_bk = ['GTK', 'GTKAgg', 'GTKCairo', 'FltkAgg', 'QtAgg', 'Qt4Agg',
 'TkAgg', 'WX', 'WXAgg', 'CocoaAgg', 'Aqt']
-non_interactive_bk = ['Agg2', 'Agg', 'Cairo', 'EMF', 'GD', 'GDK', 'Paint',
+non_interactive_bk = ['Agg2', 'Agg', 'Cairo', 'EMF', 'GDK',
 'Pdf', 'PS', 'SVG', 'Template']
 all_backends = interactive_bk + non_interactive_bk
 
Deleted: branches/transforms/lib/matplotlib/backends/backend_gd.py
===================================================================
--- branches/transforms/lib/matplotlib/backends/backend_gd.py	2007年09月10日 17:40:47 UTC (rev 3823)
+++ branches/transforms/lib/matplotlib/backends/backend_gd.py	2007年09月10日 17:45:15 UTC (rev 3824)
@@ -1,374 +0,0 @@
-"""
-A gd backend http://newcenturycomputers.net/projects/gdmodule.html
-"""
-
-
-from __future__ import division
-import sys, os, math, warnings
-
-import numpy as npy
-
-try:
- import gd
-except ImportError:
- print >>sys.stderr, 'You must first install the gd module http://newcenturycomputers.net/projects/gdmodule.html'
- sys.exit()
-
-from matplotlib.backend_bases import RendererBase, \
- GraphicsContextBase, FigureManagerBase, FigureCanvasBase
-from matplotlib import verbose
-from matplotlib._pylab_helpers import Gcf
-from matplotlib.cbook import enumerate, pieces, is_string_like
-from matplotlib.colors import colorConverter
-from matplotlib.figure import Figure
-from matplotlib.transforms import Bbox
-from matplotlib.font_manager import findfont
-# support old font names
-if (os.environ.has_key('GDFONTPATH') and not
- os.environ.has_key('TTFPATH')):
- os.environ['TTFPATH'] = os.environ['GDFONTPATH']
-
-
-
-
-PIXELS_PER_INCH = 96 # constant GD uses for screen DPI
-
-
-def round(x):
- return int(math.floor(x+0.5))
-
-
-class RendererGD(RendererBase):
- """
- The renderer handles all the drawing primitives using a graphics
- context instance that controls the colors/styles
- """
-
-
- # todo: can gd support cap and join styles?
- def __init__(self, im, dpi):
- "Initialize the renderer with a gd image instance"
- self.im = im
- self._cached = {} # a map from get_color args to colors
-
- self.width, self.height = im.size()
- self.dpi = dpi
-
-
- def get_canvas_width_height(...
 
[truncated message content]
From: <md...@us...> - 2007年09月10日 19:25:26
Revision: 3826
 http://matplotlib.svn.sourceforge.net/matplotlib/?rev=3826&view=rev
Author: mdboom
Date: 2007年09月10日 12:25:21 -0700 (2007年9月10日)
Log Message:
-----------
Running mathtext_demo.py without transforms.py/cpp. Totally broken,
though. Not surprising... ;)
Modified Paths:
--------------
 branches/transforms/lib/matplotlib/affine.py
 branches/transforms/lib/matplotlib/axes.py
 branches/transforms/lib/matplotlib/axis.py
 branches/transforms/lib/matplotlib/backend_bases.py
 branches/transforms/lib/matplotlib/backends/backend_agg.py
 branches/transforms/lib/matplotlib/bbox.py
 branches/transforms/lib/matplotlib/figure.py
 branches/transforms/lib/matplotlib/finance.py
 branches/transforms/lib/matplotlib/legend.py
 branches/transforms/lib/matplotlib/lines.py
 branches/transforms/lib/matplotlib/patches.py
 branches/transforms/lib/matplotlib/text.py
 branches/transforms/lib/matplotlib/ticker.py
 branches/transforms/src/_backend_agg.cpp
Modified: branches/transforms/lib/matplotlib/affine.py
===================================================================
--- branches/transforms/lib/matplotlib/affine.py	2007年09月10日 18:45:32 UTC (rev 3825)
+++ branches/transforms/lib/matplotlib/affine.py	2007年09月10日 19:25:21 UTC (rev 3826)
@@ -67,7 +67,10 @@
 def from_values(a, b, c, d, e, f):
 return Affine2D(Affine2D.matrix_from_values(a, b, c, d, e, f))
 from_values = staticmethod(from_values)
- 
+
+ def to_values(self):
+	return tuple(self.mtx[:2].swapaxes(0, 1).flatten())
+ 
 #@staticmethod
 def matrix_from_values(a, b, c, d, e, f):
 	affine = N.zeros((3,3), N.float_)
@@ -92,11 +95,12 @@
 
 	# This is nicer for now, however, since we can just keep a
 	# regular affine matrix around
+	# MGDTODO: Trap cases where this isn't an array and fix there
+	points = N.array(points, N.float_)
 	new_points = points.swapaxes(0, 1)
 	new_points = N.vstack((new_points, N.ones((1, points.shape[0]))))
 	result = N.dot(self.mtx, new_points)[:2]
-	result.swapaxes(0, 1)
-	return result
+	return result.swapaxes(0, 1)
 
 #@staticmethod
 def _concat(a, b):
@@ -198,10 +202,14 @@
 print transform.inverted()
 
 from bbox import Bbox
+ print "BBOX"
 boxin = Bbox([[10, 10], [320, 240]])
 boxout = Bbox([[25, 25], [640, 400]])
- trans = bbox_transform(boxin, boxout)
+ print boxin._points, boxin.xmin(), boxin.ymin(), boxin.xmax(), boxin.ymax()
+ print boxout._points, boxout.xmin(), boxout.ymin(), boxout.xmax(), boxout.ymax()
+ trans = get_bbox_transform(boxin, boxout)
 print trans
 print trans(N.array([[10, 10], [320, 240]]))
+ print trans([[10, 10]])
 
 __all__ = ['Transform', 'Affine2D']
Modified: branches/transforms/lib/matplotlib/axes.py
===================================================================
--- branches/transforms/lib/matplotlib/axes.py	2007年09月10日 18:45:32 UTC (rev 3825)
+++ branches/transforms/lib/matplotlib/axes.py	2007年09月10日 19:25:21 UTC (rev 3826)
@@ -618,10 +618,10 @@
 martist.Artist.set_figure(self, fig)
 
 l, b, w, h = self._position
- xmin = fig.bbox.ll().x()
- xmax = fig.bbox.ur().x()
- ymin = fig.bbox.ll().y()
- ymax = fig.bbox.ur().y()
+ xmin = fig.bbox.xmin()
+ xmax = fig.bbox.xmax()
+ ymin = fig.bbox.ymin()
+ ymax = fig.bbox.ymax()
 figw = xmax-xmin
 figh = ymax-ymin
 self.left = l*figw
@@ -695,9 +695,11 @@
 ACCEPTS: len(4) sequence of floats
 """
 if which in ('both', 'active'):
- # Change values within self._position--don't replace it.
- for num,val in zip(pos, self._position):
- val.set(num)
+	 # MGDTODO
+# # Change values within self._position--don't replace it.
+# for num,val in zip(pos, self._position):
+# val.set(num)
+	 self._position = pos
 if which in ('both', 'original'):
 self._originalPosition = pos
 
@@ -714,7 +716,8 @@
 self.xaxis.cla()
 self.yaxis.cla()
 
- self.dataLim.ignore(1)
+	# MGDTODO
+ # self.dataLim.ignore(1)
 self.callbacks = cbook.CallbackRegistry(('xlim_changed', 'ylim_changed'))
 
 if self._sharex is not None:
@@ -1176,7 +1179,9 @@
 # Otherwise, it will compute the bounds of it's current data
 # and the data in xydata
 #print type(x), type(y)
- self.dataLim.update_numerix(x, y, -1)
+	# MGDTODO
+ ## self.dataLim.update_numerix(x, y, -1)
+	pass
 
 def _get_verts_in_data_coords(self, trans, xys):
 if trans == self.transData:
@@ -1273,8 +1278,9 @@
 if not self.get_visible(): return
 renderer.open_group('axes')
 self.apply_aspect()
- self.transData.freeze() # eval the lazy objects
- self.transAxes.freeze()
+	# MGDTODO
+ # self.transData.freeze() # eval the lazy objects
+ # self.transAxes.freeze()
 if self.axison and self._frameon: self.axesPatch.draw(renderer)
 artists = []
 
@@ -1330,8 +1336,9 @@
 for zorder, i, a in dsu:
 a.draw(renderer)
 
- self.transData.thaw() # release the lazy objects
- self.transAxes.thaw() # release the lazy objects
+	# MGDTODO
+	# self.transData.thaw() # release the lazy objects
+ # self.transAxes.thaw() # release the lazy objects
 renderer.close_group('axes')
 self._cachedRenderer = renderer
 
Modified: branches/transforms/lib/matplotlib/axis.py
===================================================================
--- branches/transforms/lib/matplotlib/axis.py	2007年09月10日 18:45:32 UTC (rev 3825)
+++ branches/transforms/lib/matplotlib/axis.py	2007年09月10日 19:25:21 UTC (rev 3826)
@@ -261,7 +261,7 @@
 horizontalalignment='center',
 )
 
-	trans = blend_xy_sep_transformation(
+	trans = blend_xy_sep_transform(
 	 self.axes.transData, self.axes.transAxes)
 # offset the text upward with a post transformation
 trans = trans + Affine2D().translated(0, self._padPixels)
@@ -1037,7 +1037,8 @@
 bbox = bbox_union(bboxes)
 bottom = bbox.ymin()
 
- self.label.set_position( (x, bottom-self.LABELPAD*self.figure.dpi.get()/72.0))
+ self.label.set_position( (x, bottom-self.LABELPAD*self.figure.dpi/72.0))
+# self.label.set_position( (x, bottom-self.LABELPAD*self.figure.dpi.get()/72.0)) MGDTODO
 
 else:
 if not len(bboxes2):
@@ -1060,8 +1061,9 @@
 else:
 bbox = bbox_union(bboxes)
 bottom = bbox.ymin()
- self.offsetText.set_position((x, bottom-self.OFFSETTEXTPAD*self.figure.dpi.get()/72.0))
-
+ self.offsetText.set_position((x, bottom-self.OFFSETTEXTPAD*self.figure.dpi/72.0))
+# self.offsetText.set_position((x, bottom-self.OFFSETTEXTPAD*self.figure.dpi.get()/72.0)) MGDTODO
+	
 def set_ticks_position(self, position):
 """
 Set the ticks position (top, bottom, both or default)
@@ -1227,8 +1229,9 @@
 bbox = bbox_union(bboxes)
 left = bbox.xmin()
 
- self.label.set_position( (left-self.LABELPAD*self.figure.dpi.get()/72.0, y))
-
+ self.label.set_position( (left-self.LABELPAD*self.figure.dpi/72.0, y))
+	 # self.label.set_position( (left-self.LABELPAD*self.figure.dpi.get()/72.0, y)) MGDTODO
+	 
 else:
 if not len(bboxes2):
 right = self.axes.bbox.xmax()
@@ -1246,8 +1249,9 @@
 """
 x,y = self.offsetText.get_position()
 top = self.axes.bbox.ymax()
- self.offsetText.set_position((x, top+self.OFFSETTEXTPAD*self.figure.dpi.get()/72.0))
-
+ self.offsetText.set_position((x, top+self.OFFSETTEXTPAD*self.figure.dpi/72.0))
+# self.offsetText.set_position((x, top+self.OFFSETTEXTPAD*self.figure.dpi.get()/72.0)) MGDTODO
+	
 def set_offset_position(self, position):
 assert position == 'left' or position == 'right'
 
Modified: branches/transforms/lib/matplotlib/backend_bases.py
===================================================================
--- branches/transforms/lib/matplotlib/backend_bases.py	2007年09月10日 18:45:32 UTC (rev 3825)
+++ branches/transforms/lib/matplotlib/backend_bases.py	2007年09月10日 19:25:21 UTC (rev 3826)
@@ -1178,11 +1178,13 @@
 if dpi is None:
 dpi = rcParams['savefig.dpi']
 
- origDPI = self.figure.dpi.get()
+ origDPI = self.figure.dpi
 origfacecolor = self.figure.get_facecolor()
 origedgecolor = self.figure.get_edgecolor()
 
- self.figure.dpi.set(dpi)
+	# MGDTODO
+ # self.figure.dpi.set(dpi)
+ self.figure.dpi = dpi
 self.figure.set_facecolor(facecolor)
 self.figure.set_edgecolor(edgecolor)
 
@@ -1195,7 +1197,9 @@
 orientation=orientation,
 **kwargs)
 finally:
- self.figure.dpi.set(origDPI)
+	 # MGDTODO
+ # self.figure.dpi.set(origDPI)
+ self.figure.dpi = origDPI
 self.figure.set_facecolor(origfacecolor)
 self.figure.set_edgecolor(origedgecolor)
 self.figure.set_canvas(self)
Modified: branches/transforms/lib/matplotlib/backends/backend_agg.py
===================================================================
--- branches/transforms/lib/matplotlib/backends/backend_agg.py	2007年09月10日 18:45:32 UTC (rev 3825)
+++ branches/transforms/lib/matplotlib/backends/backend_agg.py	2007年09月10日 19:25:21 UTC (rev 3826)
@@ -106,14 +106,17 @@
 self.height = height
 if __debug__: verbose.report('RendererAgg.__init__ width=%s, \
 height=%s'%(width, height), 'debug-annoying')
- self._renderer = _RendererAgg(int(width), int(height), dpi.get(),
- debug=False)
+	# MGDTODO
+# self._renderer = _RendererAgg(int(width), int(height), dpi.get(),
+# 				 debug=False)
+ self._renderer = _RendererAgg(int(width), int(height), dpi,
+				 debug=False)
 if __debug__: verbose.report('RendererAgg.__init__ _RendererAgg done',
 'debug-annoying')
 self.draw_polygon = self._renderer.draw_polygon
 self.draw_rectangle = self._renderer.draw_rectangle
 self.draw_path = self._renderer.draw_path
- self.draw_lines = self._renderer.draw_lines
+ # self.draw_lines = self._renderer.draw_lines
 self.draw_markers = self._renderer.draw_markers
 self.draw_image = self._renderer.draw_image
 self.draw_line_collection = self._renderer.draw_line_collection
@@ -156,6 +159,9 @@
 y = npy.array([y1,y2], float)
 self._renderer.draw_lines(gc, x, y)
 
+ def draw_lines(self, gc, x, y, transform):
+	return self._renderer.draw_lines(gc, x, y, transform.to_values())
+	
 
 def draw_point(self, gc, x, y):
 """
@@ -173,7 +179,9 @@
 if __debug__: verbose.report('RendererAgg.draw_mathtext',
 'debug-annoying')
 ox, oy, width, height, descent, font_image, used_characters = \
- self.mathtext_parser.parse(s, self.dpi.get(), prop)
+ self.mathtext_parser.parse(s, self.dpi, prop)
+# ox, oy, width, height, descent, font_image, used_characters = \
+# self.mathtext_parser.parse(s, self.dpi.get(), prop) MGDTODO
 
 x = int(x) + ox
 y = int(y) - oy
@@ -228,7 +236,9 @@
 
 if ismath:
 ox, oy, width, height, descent, fonts, used_characters = \
- self.mathtext_parser.parse(s, self.dpi.get(), prop)
+ self.mathtext_parser.parse(s, self.dpi, prop)
+# ox, oy, width, height, descent, fonts, used_characters = \
+# self.mathtext_parser.parse(s, self.dpi.get(), prop) MGDTODO
 return width, height, descent
 font = self._get_agg_font(prop)
 font.set_text(s, 0.0, flags=LOAD_DEFAULT) # the width and height of unrotated string
@@ -302,7 +312,8 @@
 
 font.clear()
 size = prop.get_size_in_points()
- font.set_size(size, self.dpi.get())
+ font.set_size(size, self.dpi)
+ # font.set_size(size, self.dpi.get()) MGDTODO
 
 return font
 
@@ -380,7 +391,9 @@
 
 def get_renderer(self):
 l,b,w,h = self.figure.bbox.get_bounds()
- key = w, h, self.figure.dpi.get()
+	# MGDTODO
+ # key = w, h, self.figure.dpi.get()
+ key = w, h, self.figure.dpi
 try: self._lastKey, self.renderer
 except AttributeError: need_new_renderer = True
 else: need_new_renderer = (self._lastKey != key)
Modified: branches/transforms/lib/matplotlib/bbox.py
===================================================================
--- branches/transforms/lib/matplotlib/bbox.py	2007年09月10日 18:45:32 UTC (rev 3825)
+++ branches/transforms/lib/matplotlib/bbox.py	2007年09月10日 19:25:21 UTC (rev 3826)
@@ -6,9 +6,31 @@
 
 import numpy as N
 
+class Interval:
+ def __init__(self, bounds):
+	self._bounds = N.array(bounds, N.float_)
+
+ def contains(self, value):
+	bounds = self._bounds
+	return value >= bounds[0] and value <= bounds[1]
+
+ def contains_open(self, value):
+	bounds = self._bounds
+	return value > bounds[0] and value < bounds[1]
+
+ def get_bounds(self):
+	return self._bounds
+
+ def set_bounds(self, lower, upper):
+	self._bounds = lower, upper
+
+ def span(self):
+	bounds = self._bounds
+	return bounds[1] - bounds[0]
+	
 class Bbox:
 def __init__(self, points):
-	self._points = N.array(points)
+	self._points = N.array(points, N.float_)
 
 #@staticmethod
 def unit():
@@ -23,7 +45,10 @@
 #@staticmethod
 def from_lbrt(left, bottom, right, top):
 	return Bbox([[left, bottom], [right, top]])
- from_lbwh = staticmethod(from_lbwh)
+ from_lbrt = staticmethod(from_lbrt)
+
+ def copy(self):
+	return Bbox(self._points.copy())
 
 # MGDTODO: Probably a more efficient ways to do this...
 def xmin(self):
@@ -45,15 +70,29 @@
 	return self.ymax() - self.ymin()
 
 def transform(self, transform):
-	return Bbox(transform(points))
+	return Bbox(transform(self._points))
 
 def inverse_transform(self, transform):
-	return Bbox(transform.inverted()(points))
+	return Bbox(transform.inverted()(self._points))
 
 def get_bounds(self):
 	return (self.xmin(), self.ymin(),
 		self.xmax() - self.xmin(), self.ymax() - self.ymin())
- 
+
+ def intervalx(self):
+	return Interval(self._points[0])
+
+ def intervaly(self):
+	return Interval(self._points[1])
+
+ def scaled(self, sw, sh):
+	width = self.width()
+	height = self.height()
+	deltaw = (sw * width - width) / 2.0
+	deltah = (sh * height - height) / 2.0
+	a = N.array([[-deltaw, -deltah], [deltaw, deltah]])
+	return Bbox(self._points + a)
+	
 def lbwh_to_bbox(left, bottom, width, height):
 return Bbox([[left, bottom], [left + width, bottom + height]])
 
@@ -67,18 +106,18 @@
 	return bboxes[0]
 
 bbox = bboxes[0]
- xmin = bbox.xmin
- ymin = bbox.ymin
- xmax = bbox.xmax
- ymax = bbox.ymax
+ xmin = bbox.xmin()
+ ymin = bbox.ymin()
+ xmax = bbox.xmax()
+ ymax = bbox.ymax()
 
 for bbox in bboxes[1:]:
-	xmin = min(xmin, bbox.xmin)
-	ymin = min(ymin, bbox.ymin)
-	xmax = max(xmax, bbox.xmax)
-	ymax = max(ymax, bbox.ymax)
+	xmin = min(xmin, bbox.xmin())
+	ymin = min(ymin, bbox.ymin())
+	xmax = max(xmax, bbox.xmax())
+	ymax = max(ymax, bbox.ymax())
 
- return Bbox(xmin, ymin, xmax, ymax)
+ return Bbox.from_lbrt(xmin, ymin, xmax, ymax)
 
 # MGDTODO: There's probably a better place for this
 def nonsingular(vmin, vmax, expander=0.001, tiny=1e-15, increasing=True):
Modified: branches/transforms/lib/matplotlib/figure.py
===================================================================
--- branches/transforms/lib/matplotlib/figure.py	2007年09月10日 18:45:32 UTC (rev 3825)
+++ branches/transforms/lib/matplotlib/figure.py	2007年09月10日 19:25:21 UTC (rev 3826)
@@ -129,9 +129,10 @@
 if edgecolor is None: edgecolor = rcParams['figure.edgecolor']
 
 self.dpi = dpi
+	self.figsize = figsize
 	self.bbox = Bbox.from_lbwh(0, 0,
-				 self.figsize[0] * dpi,
-				 self.figsize[1] * dpi)
+				 figsize[0] * dpi,
+				 figsize[1] * dpi)
 	
 self.frameon = frameon
 
@@ -581,7 +582,8 @@
 #print 'figure draw'
 if not self.get_visible(): return
 renderer.open_group('figure')
- self.transFigure.freeze() # eval the lazy objects
+	# MGDTODO
+ # self.transFigure.freeze() # eval the lazy objects
 
 if self.frameon: self.figurePatch.draw(renderer)
 
@@ -615,7 +617,8 @@
 for legend in self.legends:
 legend.draw(renderer)
 
- self.transFigure.thaw() # release the lazy objects
+	# MGDTODO
+	# self.transFigure.thaw() # release the lazy objects
 renderer.close_group('figure')
 
 self._cachedRenderer = renderer
Modified: branches/transforms/lib/matplotlib/finance.py
===================================================================
--- branches/transforms/lib/matplotlib/finance.py	2007年09月10日 18:45:32 UTC (rev 3825)
+++ branches/transforms/lib/matplotlib/finance.py	2007年09月10日 19:25:21 UTC (rev 3826)
@@ -22,8 +22,7 @@
 from matplotlib.colors import colorConverter
 from lines import Line2D, TICKLEFT, TICKRIGHT
 from patches import Rectangle
-from matplotlib.transforms import scale_transform, Value, zero, one, \
- scale_sep_transform, blend_xy_sep_transform
+from matplotlib.affine import Affine2D
 
 
 
@@ -335,9 +334,9 @@
 offsetsClose = [ (i, close) for i, close in zip(xrange(len(closes)), closes) if close != -1 ]
 
 
- scale = ax.figure.dpi * Value(1/72.0)
+ scale = ax.figure.dpi * (1.0/72.0)
 
- tickTransform = scale_transform( scale, zero())
+ tickTransform = Affine2D().scaled(scale, 0.0)
 
 r,g,b = colorConverter.to_rgb(colorup)
 colorup = r,g,b,1
@@ -424,10 +423,10 @@
 
 offsetsBars = [ (i, open) for i,open in zip(xrange(len(opens)), opens) if open != -1 ]
 
- sx = ax.figure.dpi * Value(1/72.0) # scale for points
+ sx = ax.figure.dpi * (1.0/72.0) # scale for points
 sy = (ax.bbox.ur().y() - ax.bbox.ll().y()) / (ax.viewLim.ur().y() - ax.viewLim.ll().y())
 
- barTransform = scale_sep_transform(sx,sy)
+ barTransform = Affine2D().scaled(sx,sy)
 
 
 
@@ -512,10 +511,10 @@
 
 bars = [ ( (left, 0), (left, v), (right, v), (right, 0)) for v in volumes if v != -1 ]
 
- sx = ax.figure.dpi * Value(1/72.0) # scale for points
+ sx = ax.figure.dpi * (1.0/72.0) # scale for points
 sy = (ax.bbox.ur().y() - ax.bbox.ll().y()) / (ax.viewLim.ur().y() - ax.viewLim.ll().y())
 
- barTransform = scale_sep_transform(sx,sy)
+ barTransform = Affine2D().scaled(sx,sy)
 
 offsetsBars = [ (i, 0) for i,v in enumerate(volumes) if v != -1 ]
 
@@ -602,10 +601,10 @@
 
 bars = [ ( (left, 0), (left, volume), (right, volume), (right, 0)) for d, open, close, high, low, volume in quotes]
 
- sx = ax.figure.dpi * Value(1/72.0) # scale for points
+ sx = ax.figure.dpi * (1.0/72.0) # scale for points
 sy = (ax.bbox.ur().y() - ax.bbox.ll().y()) / (ax.viewLim.ur().y() - ax.viewLim.ll().y())
 
- barTransform = scale_sep_transform(sx,sy)
+ barTransform = Affine2D().scaled(sx,sy)
 
 dates = [d for d, open, close, high, low, volume in quotes]
 offsetsBars = [(d, 0) for d in dates]
@@ -662,10 +661,10 @@
 
 bars = [ ( (left, 0), (left, v), (right, v), (right, 0)) for v in vals if v != -1 ]
 
- sx = ax.figure.dpi * Value(1/72.0) # scale for points
+ sx = ax.figure.dpi * (1.0/72.0) # scale for points
 sy = (ax.bbox.ur().y() - ax.bbox.ll().y()) / (ax.viewLim.ur().y() - ax.viewLim.ll().y())
 
- barTransform = scale_sep_transform(sx,sy)
+ barTransform = Affine2D().scaled(sx,sy)
 
 offsetsBars = [ (i, 0) for i,v in enumerate(vals) if v != -1 ]
 
Modified: branches/transforms/lib/matplotlib/legend.py
===================================================================
--- branches/transforms/lib/matplotlib/legend.py	2007年09月10日 18:45:32 UTC (rev 3825)
+++ branches/transforms/lib/matplotlib/legend.py	2007年09月10日 19:25:21 UTC (rev 3826)
@@ -224,7 +224,7 @@
 a.set_transform(self.get_transform())
 
 def _approx_text_height(self):
- return self.fontsize/72.0*self.figure.dpi.get()/self.parent.bbox.height()
+ return self.fontsize/72.0*self.figure.dpi/self.parent.bbox.height()
 
 
 def draw(self, renderer):
@@ -531,7 +531,7 @@
 if not len(self.legendHandles) and not len(self.texts): return
 def get_tbounds(text): #get text bounds in axes coords
 bbox = text.get_window_extent(renderer)
- bboxa = inverse_transform_bbox(self.get_transform(), bbox)
+ bboxa = bbox.inverse_transform(self.get_transform())
 return bboxa.get_bounds()
 
 hpos = []
@@ -559,9 +559,11 @@
 handle.set_height(h/2)
 
 # Set the data for the legend patch
- bbox = self._get_handle_text_bbox(renderer).deepcopy()
+	# MGDTODO: This copy may no longer be needed now that Bboxes are
+	# essentially immutable
+ bbox = self._get_handle_text_bbox(renderer).copy()
 
- bbox.scale(1 + self.pad, 1 + self.pad)
+ bbox = bbox.scaled(1 + self.pad, 1 + self.pad)
 l,b,w,h = bbox.get_bounds()
 self.legendPatch.set_bounds(l,b,w,h)
 
Modified: branches/transforms/lib/matplotlib/lines.py
===================================================================
--- branches/transforms/lib/matplotlib/lines.py	2007年09月10日 18:45:32 UTC (rev 3825)
+++ branches/transforms/lib/matplotlib/lines.py	2007年09月10日 19:25:21 UTC (rev 3826)
@@ -362,8 +362,13 @@
 else:
 x, y = self._get_plottable()
 
-
- x, y = self.get_transform().numerix_x_y(x, y)
+	# MGDTODO: Put this in a single Nx2 array, rather than these
+	# separate ones
+	#### Conversion code
+	a = npy.vstack((x, y)).swapaxes(0, 1)
+	####
+ x, y = self.get_transform()(a)
+	
 #x, y = self.get_transform().seq_x_y(x, y)
 
 left = min(x)
@@ -373,7 +378,8 @@
 
 # correct for marker size, if any
 if self._marker is not None:
- ms = self._markersize/72.0*self.figure.dpi.get()
+ ms = self._markersize/72.0*self.figure.dpi
+ # ms = self._markersize/72.0*self.figure.dpi.get() MGDTODO
 left -= ms/2
 bottom -= ms/2
 width += ms
Modified: branches/transforms/lib/matplotlib/patches.py
===================================================================
--- branches/transforms/lib/matplotlib/patches.py	2007年09月10日 18:45:32 UTC (rev 3825)
+++ branches/transforms/lib/matplotlib/patches.py	2007年09月10日 19:25:21 UTC (rev 3826)
@@ -209,8 +209,13 @@
 gc.set_hatch(self._hatch )
 
 verts = self.get_verts()
- tverts = self.get_transform().seq_xy_tups(verts)
+ tverts = self.get_transform()(verts)
 
+	# MGDTODO: This result is an Nx2 numpy array, which could be passed
+	# directly to renderer.draw_polygon. However, it currently expects
+	# a list of tuples so we're converting it to that now.
+	tverts = [tuple(x) for x in tverts]
+	
 renderer.draw_polygon(gc, rgbFace, tverts)
 
 
Modified: branches/transforms/lib/matplotlib/text.py
===================================================================
--- branches/transforms/lib/matplotlib/text.py	2007年09月10日 18:45:32 UTC (rev 3825)
+++ branches/transforms/lib/matplotlib/text.py	2007年09月10日 19:25:21 UTC (rev 3826)
@@ -151,7 +151,7 @@
 def _get_xy_display(self):
 'get the (possibly unit converted) transformed x,y in display coords'
 x, y = self.get_position()
- return self.get_transform().xy_tup((x,y))
+ return self.get_transform()([[x,y]])[0]
 
 def _get_multialignment(self):
 if self._multialignment is not None: return self._multialignment
@@ -275,7 +275,8 @@
 ty = [float(v[1][0])+offsety for v in xys]
 
 # now inverse transform back to data coords
- xys = [self.get_transform().inverse_xy_tup( xy ) for xy in zip(tx, ty)]
+	inverse_transform = self.get_transform().inverted()
+ xys = inverse_transform(zip(tx, ty))
 
 xs, ys = zip(*xys)
 
@@ -328,7 +329,7 @@
 return
 
 for line, wh, x, y in info:
- x, y = trans.xy_tup((x, y))
+ x, y = trans([[x, y]])[0]
 
 if renderer.flipy():
 canvasw, canvash = renderer.get_canvas_width_height()
@@ -405,7 +406,7 @@
 return (x, y, self._text, self._color,
 self._verticalalignment, self._horizontalalignment,
 hash(self._fontproperties), self._rotation,
- self.get_transform().as_vec6_val(),
+ self.get_transform().to_values(),
 )
 
 def get_text(self):
Modified: branches/transforms/lib/matplotlib/ticker.py
===================================================================
--- branches/transforms/lib/matplotlib/ticker.py	2007年09月10日 18:45:32 UTC (rev 3825)
+++ branches/transforms/lib/matplotlib/ticker.py	2007年09月10日 19:25:21 UTC (rev 3826)
@@ -115,12 +115,11 @@
 import matplotlib as mpl
 from matplotlib import verbose, rcParams
 from matplotlib import cbook
-from matplotlib import transforms as mtrans
+from matplotlib import bbox as mbbox
 
 
 
 
-
 class TickHelper:
 
 viewInterval = None
@@ -149,8 +148,8 @@
 cases where the Intervals do not need to be updated
 automatically.
 '''
- self.dataInterval = mtrans.Interval(mtrans.Value(vmin), mtrans.Value(vmax))
- self.viewInterval = mtrans.Interval(mtrans.Value(vmin), mtrans.Value(vmax))
+ self.dataInterval = mbbox.Interval([vmin, vmax])
+ self.viewInterval = mbbox.Interval([vmin, vmax])
 
 class Formatter(TickHelper):
 """
@@ -572,7 +571,7 @@
 def autoscale(self):
 'autoscale the view limits'
 self.verify_intervals()
- return mtrans.nonsingular(*self.dataInterval.get_bounds())
+ return mbbox.nonsingular(*self.dataInterval.get_bounds())
 
 def pan(self, numsteps):
 'Pan numticks (can be positive or negative)'
@@ -714,7 +713,7 @@
 vmin = math.floor(scale*vmin)/scale
 vmax = math.ceil(scale*vmax)/scale
 
- return mtrans.nonsingular(vmin, vmax)
+ return mbbox.nonsingular(vmin, vmax)
 
 
 def closeto(x,y):
@@ -798,7 +797,7 @@
 vmin -=1
 vmax +=1
 
- return mtrans.nonsingular(vmin, vmax)
+ return mbbox.nonsingular(vmin, vmax)
 
 def scale_range(vmin, vmax, n = 1, threshold=100):
 dv = abs(vmax - vmin)
@@ -866,13 +865,13 @@
 def __call__(self):
 self.verify_intervals()
 vmin, vmax = self.viewInterval.get_bounds()
- vmin, vmax = mtrans.nonsingular(vmin, vmax, expander = 0.05)
+ vmin, vmax = mbbox.nonsingular(vmin, vmax, expander = 0.05)
 return self.bin_boundaries(vmin, vmax)
 
 def autoscale(self):
 self.verify_intervals()
 dmin, dmax = self.dataInterval.get_bounds()
- dmin, dmax = mtrans.nonsingular(dmin, dmax, expander = 0.05)
+ dmin, dmax = mbbox.nonsingular(dmin, dmax, expander = 0.05)
 return npy.take(self.bin_boundaries(dmin, dmax), [0,-1])
 
 
@@ -973,7 +972,7 @@
 if vmin==vmax:
 vmin = decade_down(vmin,self._base)
 vmax = decade_up(vmax,self._base)
- return mtrans.nonsingular(vmin, vmax)
+ return mbbox.nonsingular(vmin, vmax)
 
 class AutoLocator(MaxNLocator):
 def __init__(self):
Modified: branches/transforms/src/_backend_agg.cpp
===================================================================
--- branches/transforms/src/_backend_agg.cpp	2007年09月10日 18:45:32 UTC (rev 3825)
+++ branches/transforms/src/_backend_agg.cpp	2007年09月10日 19:25:21 UTC (rev 3826)
@@ -44,6 +44,27 @@
 #define M_PI_2 1.57079632679489661923
 #endif
 
+agg::trans_affine py_sequence_to_agg_transformation_matrix(const Py::Object& obj) {
+ Py::SeqBase<Py::Float> seq;
+ try {
+ seq = obj;
+ } catch(...) {
+ throw Py::ValueError("Transformation matrix must be given as a 6-element list.");
+ }
+
+ if (seq.size() != 6) {
+ throw Py::ValueError("Transformation matrix must be given as a 6-element list.");
+ }
+
+ agg::trans_affine xytrans = agg::trans_affine
+ (Py::Float(seq[0]), 
+ Py::Float(seq[1]), 
+ Py::Float(seq[2]), 
+ Py::Float(seq[3]), 
+ Py::Float(seq[4]), 
+ Py::Float(seq[5]));
+}
+
 GCAgg::GCAgg(const Py::Object &gc, double dpi, bool snapto) :
 dpi(dpi), snapto(snapto), isaa(true), linewidth(1.0), alpha(1.0),
 cliprect(NULL), clippath(NULL), 
@@ -646,7 +667,8 @@
 Py::SeqBase<Py::Object> linewidths = args[4];
 Py::SeqBase<Py::Object> linestyle = args[5];
 Py::SeqBase<Py::Object> antialiaseds = args[6];
- 
+
+ // MGDTODO: Verify we don't need this offset stuff anymore
 bool usingOffsets = args[7].ptr()!=Py_None;
 Py::SeqBase<Py::Object> offsets;
 Transformation* transOffset=NULL;
@@ -1534,24 +1556,14 @@
 //path_t transpath(path, xytrans);
 _process_alpha_mask(gc);
 
- Transformation* mpltransform = static_cast<Transformation*>(args[3].ptr());
+ agg::trans_affine xytrans = py_sequence_to_agg_transformation_matrix(args[3]);
 
- double a, b, c, d, tx, ty;
- try {
- mpltransform->affine_params_api(&a, &b, &c, &d, &tx, &ty);
- }
- catch(...) {
- throw Py::ValueError("Domain error on affine_params_api in RendererAgg::draw_lines");
- }
-
- agg::trans_affine xytrans = agg::trans_affine(a,b,c,d,tx,ty);
-
-
 agg::path_storage path;
 
+ // MGDTODO
+ bool needNonlinear = false;
+ // mpltransform->need_nonlinear_api();
 
- bool needNonlinear = mpltransform->need_nonlinear_api();
-
 double thisx(0.0), thisy(0.0);
 double origdx(0.0), origdy(0.0), origdNorm2(0);
 bool moveto = true;
@@ -1584,7 +1596,8 @@
 
 if (needNonlinear)
 try {
- mpltransform->nonlinear_only_api(&thisx, &thisy);
+	// MGDTODO
+ // mpltransform->nonlinear_only_api(&thisx, &thisy);
 }
 catch (...) {
 moveto = true;
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
From: <md...@us...> - 2007年09月11日 17:56:14
Revision: 3830
 http://matplotlib.svn.sourceforge.net/matplotlib/?rev=3830&view=rev
Author: mdboom
Date: 2007年09月11日 10:56:13 -0700 (2007年9月11日)
Log Message:
-----------
Just marking a milestone -- about to totally rip things up again.
Modified Paths:
--------------
 branches/transforms/lib/matplotlib/affine.py
 branches/transforms/lib/matplotlib/artist.py
 branches/transforms/lib/matplotlib/axes.py
 branches/transforms/lib/matplotlib/backend_bases.py
 branches/transforms/lib/matplotlib/backends/backend_agg.py
 branches/transforms/lib/matplotlib/backends/backend_tkagg.py
 branches/transforms/lib/matplotlib/bbox.py
 branches/transforms/lib/matplotlib/figure.py
 branches/transforms/lib/matplotlib/lines.py
 branches/transforms/lib/matplotlib/patches.py
 branches/transforms/lib/matplotlib/text.py
 branches/transforms/src/_backend_agg.cpp
Modified: branches/transforms/lib/matplotlib/affine.py
===================================================================
--- branches/transforms/lib/matplotlib/affine.py	2007年09月11日 12:46:27 UTC (rev 3829)
+++ branches/transforms/lib/matplotlib/affine.py	2007年09月11日 17:56:13 UTC (rev 3830)
@@ -58,10 +58,8 @@
 	self.mtx = matrix
 
 def __repr__(self):
-	return repr(self.mtx)
-
- def __str__(self):
-	return str(self.mtx)
+	return "Affine2D(%s)" % repr(self.mtx)
+ __str__ = __repr__
 
 #@staticmethod
 def from_values(a, b, c, d, e, f):
@@ -156,8 +154,8 @@
 
 class BlendedAffine2D(Affine2D):
 def __init__(self, x_transform, y_transform):
-	assert isinstance(x_transform, Affine2D)
-	assert isinstance(y_transform, Affine2D)
+#	assert isinstance(x_transform, Affine2D)
+#	assert isinstance(y_transform, Affine2D)
 	assert x_transform.is_separable()
 	assert y_transform.is_separable()
 	x_mtx = x_transform.mtx
Modified: branches/transforms/lib/matplotlib/artist.py
===================================================================
--- branches/transforms/lib/matplotlib/artist.py	2007年09月11日 12:46:27 UTC (rev 3829)
+++ branches/transforms/lib/matplotlib/artist.py	2007年09月11日 17:56:13 UTC (rev 3830)
@@ -138,6 +138,7 @@
 
 ACCEPTS: a matplotlib.transform transformation instance
 """
+	print "set_transform", t
 self._transform = t
 self._transformSet = True
 self.pchanged()
Modified: branches/transforms/lib/matplotlib/axes.py
===================================================================
--- branches/transforms/lib/matplotlib/axes.py	2007年09月11日 12:46:27 UTC (rev 3829)
+++ branches/transforms/lib/matplotlib/axes.py	2007年09月11日 17:56:13 UTC (rev 3830)
@@ -10,9 +10,9 @@
 
 from matplotlib import artist as martist
 from matplotlib import affine as maffine
-from matplotlib import bbox as mbbox
 from matplotlib import agg
 from matplotlib import axis as maxis
+from matplotlib import bbox as mbbox
 from matplotlib import cbook
 from matplotlib import collections as mcoll
 from matplotlib import colors as mcolors
@@ -33,9 +33,9 @@
 
 iterable = cbook.iterable
 is_string_like = cbook.is_string_like
+Wrapper = cbook.Wrapper
 
 
-
 def delete_masked_points(*args):
 """
 Find all masked points in a set of arguments, and return
@@ -437,7 +437,6 @@
 1 : 'log',
 }
 
- 
 def __str__(self):
 return "Axes(%g,%g;%gx%g)"%(self._position[0].get(),self._position[1].get(),
 self._position[2].get(),self._position[3].get())
@@ -535,7 +534,6 @@
 if self.yaxis is not None:
 self._ycid = self.yaxis.callbacks.connect('units finalize', self.relim)
 
-
 def get_window_extent(self, *args, **kwargs):
 'get the axes bounding box in display space; args and kwargs are empty'
 return self.bbox
@@ -655,16 +653,16 @@
 bottom = 0.0
 top = 1.0
 
-
-
 self.viewLim = Bbox.from_lbrt(left, bottom, right, top)
- self.dataLim = Bbox.unit()
-
+	self.dataLim = Bbox.unit()
+	
 self.transData = maffine.get_bbox_transform(
 self.viewLim, self.bbox)
 self.transAxes = maffine.get_bbox_transform(
- Bbox.unit(), self.bbox)
+ self.dataLim, self.bbox)
 
+	print "_set_lim_and_transforms", self.viewLim, self.transData, self.dataLim, self.transAxes, self.bbox
+
 	# MGDTODO
 # if self._sharex:
 # self.transData.set_funcx(self._sharex.transData.get_funcx())
@@ -677,7 +675,8 @@
 if original:
 return self._originalPosition[:]
 else:
- return [val.get() for val in self._position]
+ return self._position[:]
+	 # return [val.get() for val in self._position]
 
 def set_position(self, pos, which='both'):
 """
@@ -699,10 +698,13 @@
 # # Change values within self._position--don't replace it.
 # for num,val in zip(pos, self._position):
 # val.set(num)
+	 print "set_position", self._position, pos
 	 self._position = pos
+	 # MGDTODO: side-effects
 if which in ('both', 'original'):
 self._originalPosition = pos
-
+	 
+	 
 def _set_artist_props(self, a):
 'set the boilerplate props for artists added to axes'
 a.set_figure(self.figure)
@@ -1181,7 +1183,10 @@
 #print type(x), type(y)
 	# MGDTODO
 ## self.dataLim.update_numerix(x, y, -1)
-	pass
+	print "update_datalim_numerix", self.dataLim,
+	self.dataLim = mbbox.Bbox.from_data(x, y)
+	print self.dataLim
+	# MGDTODO side-effects
 
 def _get_verts_in_data_coords(self, trans, xys):
 if trans == self.transData:
@@ -1190,8 +1195,8 @@
 # display and then back to data to get it in data units
 #xys = trans.seq_xy_tups(xys)
 #return [ self.transData.inverse_xy_tup(xy) for xy in xys]
- xys = trans.numerix_xy(npy.asarray(xys))
- return self.transData.inverse_numerix_xy(xys)
+ xys = trans(npy.asarray(xys))
+ return self.transData.inverted()(xys)
 
 def _process_unit_info(self, xdata=None, ydata=None, kwargs=None):
 'look for unit kwargs and update the axis instances as necessary'
@@ -1242,7 +1247,8 @@
 axis direction reversal that has already been done.
 """
 # if image data only just use the datalim
-
+	print "autoscale_view"
+	
 if not self._autoscaleon: return
 if (tight or (len(self.images)>0 and
 len(self.lines)==0 and
@@ -1278,7 +1284,7 @@
 if not self.get_visible(): return
 renderer.open_group('axes')
 self.apply_aspect()
-	# MGDTODO
+	# MGDTODO -- this is where we can finalize all of the transforms
 # self.transData.freeze() # eval the lazy objects
 # self.transAxes.freeze()
 if self.axison and self._frameon: self.axesPatch.draw(renderer)
@@ -1544,9 +1550,12 @@
 # raise ValueError('Cannot set nonpositive limits with log transform')
 
 xmin, xmax = mbbox.nonsingular(xmin, xmax, increasing=False)
- self.viewLim.intervalx().set_bounds(xmin, xmax)
- if emit: self.callbacks.process('xlim_changed', self)
 
+	# MGDTODO: This is fairly cumbersome
+	# MGDTODO: side-effects on x-bounds should propagate
+	self.viewLim = mbbox.Bbox.from_lbrt(xmin, self.viewLim.ymin(), xmax, self.viewLim.ymax())
+	print 'set_xlim', self.viewLim
+	
 return xmin, xmax
 
 def get_xscale(self):
@@ -1649,7 +1658,7 @@
 ACCEPTS: len(2) sequence of floats
 """
 
-
+	print "set_ylim", ymin, ymax, emit
 if ymax is None and iterable(ymin):
 ymin,ymax = ymin
 
@@ -1669,9 +1678,11 @@
 # raise ValueError('Cannot set nonpositive limits with log transform')
 
 ymin, ymax = mbbox.nonsingular(ymin, ymax, increasing=False)
- self.viewLim.intervaly().set_bounds(ymin, ymax)
+	# MGDTODO: side-effects on y-bounds should propagate
+	self.viewLim = mbbox.Bbox.from_lbrt(self.viewLim.xmin(), ymin, self.viewLim.xmax(), ymax)
 if emit: self.callbacks.process('ylim_changed', self)
-
+	print "set_ylim", self.viewLim
+	
 return ymin, ymax
 
 def get_yscale(self):
@@ -2158,7 +2169,7 @@
 %(Annotation)s
 """
 a = mtext.Annotation(*args, **kwargs)
- a.set_transform(maffine.Affine2D.identity())
+ a.set_transform(maffine.Affine2D())
 self._set_artist_props(a)
 if kwargs.has_key('clip_on'): a.set_clip_box(self.bbox)
 self.texts.append(a)
@@ -2197,7 +2208,7 @@
 %(Line2D)s
 """
 
- trans = maffine.blend_xy_sep_transform( self.transAxes, self.transData)
+ trans = maffine.blend_xy_sep_transform(self.transAxes, self.transData)
 l, = self.plot([xmin,xmax], [y,y], transform=trans, scalex=False, **kwargs)
 return l
 
Modified: branches/transforms/lib/matplotlib/backend_bases.py
===================================================================
--- branches/transforms/lib/matplotlib/backend_bases.py	2007年09月11日 12:46:27 UTC (rev 3829)
+++ branches/transforms/lib/matplotlib/backend_bases.py	2007年09月11日 17:56:13 UTC (rev 3830)
@@ -752,7 +752,7 @@
 else: # Just found one hit
 self.inaxes = axes_list[0]
 
- try: xdata, ydata = self.inaxes.transData.inverse_xy_tup((x, y))
+ try: xdata, ydata = self.inaxes.transData.inverted()([[x, y]])[0]
 except ValueError:
 self.xdata = None
 self.ydata = None
Modified: branches/transforms/lib/matplotlib/backends/backend_agg.py
===================================================================
--- branches/transforms/lib/matplotlib/backends/backend_agg.py	2007年09月11日 12:46:27 UTC (rev 3829)
+++ branches/transforms/lib/matplotlib/backends/backend_agg.py	2007年09月11日 17:56:13 UTC (rev 3830)
@@ -113,11 +113,12 @@
 				 debug=False)
 if __debug__: verbose.report('RendererAgg.__init__ _RendererAgg done',
 'debug-annoying')
- self.draw_polygon = self._renderer.draw_polygon
+ # self.draw_polygon = self._renderer.draw_polygon
 self.draw_rectangle = self._renderer.draw_rectangle
 self.draw_path = self._renderer.draw_path
+	# MGDTODO -- remove these lines
 # self.draw_lines = self._renderer.draw_lines
- self.draw_markers = self._renderer.draw_markers
+ # self.draw_markers = self._renderer.draw_markers
 self.draw_image = self._renderer.draw_image
 self.draw_line_collection = self._renderer.draw_line_collection
 self.draw_quad_mesh = self._renderer.draw_quad_mesh
@@ -161,8 +162,13 @@
 
 def draw_lines(self, gc, x, y, transform):
 	return self._renderer.draw_lines(gc, x, y, transform.to_values())
-	
 
+ def draw_markers(self, gc, path, color, x, y, transform):
+	return self._renderer.draw_markers(gc, path, color, x, y, transform.to_values())
+
+ def draw_polygon(self, *args):
+	return self._renderer.draw_polygon(*args)
+ 
 def draw_point(self, gc, x, y):
 """
 Draw a single point at x,y
@@ -325,8 +331,10 @@
 """
 if __debug__: verbose.report('RendererAgg.points_to_pixels',
 'debug-annoying')
- return points*self.dpi.get()/72.0
-
+	# MGDTODO
+ # return points*self.dpi.get()/72.0
+ return points*self.dpi/72.0
+ 
 def tostring_rgb(self):
 if __debug__: verbose.report('RendererAgg.tostring_rgb',
 'debug-annoying')
Modified: branches/transforms/lib/matplotlib/backends/backend_tkagg.py
===================================================================
--- branches/transforms/lib/matplotlib/backends/backend_tkagg.py	2007年09月11日 12:46:27 UTC (rev 3829)
+++ branches/transforms/lib/matplotlib/backends/backend_tkagg.py	2007年09月11日 17:56:13 UTC (rev 3830)
@@ -175,7 +175,8 @@
 self._resize_callback(event)
 
 # compute desired figure size in inches
- dpival = self.figure.dpi.get()
+	# dpival = self.figure.dpi.get() MGDTODO
+	dpival = self.figure.dpi
 winch = width/dpival
 hinch = height/dpival
 self.figure.set_size_inches(winch, hinch)
Modified: branches/transforms/lib/matplotlib/bbox.py
===================================================================
--- branches/transforms/lib/matplotlib/bbox.py	2007年09月11日 12:46:27 UTC (rev 3829)
+++ branches/transforms/lib/matplotlib/bbox.py	2007年09月11日 17:56:13 UTC (rev 3830)
@@ -21,9 +21,6 @@
 def get_bounds(self):
 	return self._bounds
 
- def set_bounds(self, lower, upper):
-	self._bounds = lower, upper
-
 def span(self):
 	bounds = self._bounds
 	return bounds[1] - bounds[0]
@@ -47,8 +44,23 @@
 	return Bbox([[left, bottom], [right, top]])
 from_lbrt = staticmethod(from_lbrt)
 
+ #@staticmethod
+ def from_data(x, y):
+	return Bbox([[x.min(), y.min()], [x.max(), y.max()]])
+ from_data = staticmethod(from_data)
+ 
 def copy(self):
 	return Bbox(self._points.copy())
+
+ def __repr__(self):
+	return 'Bbox(%s)' % repr(self._points)
+ __str__ = __repr__
+
+ def __cmp__(self, other):
+	# MGDTODO: Totally suboptimal
+	if isinstance(other, Bbox):
+	 return (self._points == other._points).all()
+	return -1
 
 # MGDTODO: Probably a more efficient ways to do this...
 def xmin(self):
@@ -79,6 +91,7 @@
 	return (self.xmin(), self.ymin(),
 		self.xmax() - self.xmin(), self.ymax() - self.ymin())
 
+ # MGDTODO: This is an inefficient way to do this
 def intervalx(self):
 	return Interval(self._points[0])
 
@@ -92,10 +105,11 @@
 	deltah = (sh * height - height) / 2.0
 	a = N.array([[-deltaw, -deltah], [deltaw, deltah]])
 	return Bbox(self._points + a)
-	
-def lbwh_to_bbox(left, bottom, width, height):
- return Bbox([[left, bottom], [left + width, bottom + height]])
- 
+
+ def contains(self, x, y):
+	return (x >= self.xmin() and x <= self.xmax() and
+		y >= self.ymin() and y <= self.ymax())
+
 def bbox_union(bboxes):
 """
 Return the Bbox that bounds all bboxes
Modified: branches/transforms/lib/matplotlib/figure.py
===================================================================
--- branches/transforms/lib/matplotlib/figure.py	2007年09月11日 12:46:27 UTC (rev 3829)
+++ branches/transforms/lib/matplotlib/figure.py	2007年09月11日 17:56:13 UTC (rev 3830)
@@ -105,8 +105,9 @@
 class Figure(Artist):
 
 def __str__(self):
- return "Figure(%gx%g)"%(self.figwidth.get(),self.figheight.get())
-
+ return "Figure(%gx%g)"%(self.figwidth, self.figheight)
+ # return "Figure(%gx%g)"%(self.figwidth.get(),self.figheight.get())
+ 
 def __init__(self,
 figsize = None, # defaults to rc figure.figsize
 dpi = None, # defaults to rc figure.dpi
@@ -129,10 +130,9 @@
 if edgecolor is None: edgecolor = rcParams['figure.edgecolor']
 
 self.dpi = dpi
-	self.figsize = figsize
-	self.bbox = Bbox.from_lbwh(0, 0,
-				 figsize[0] * dpi,
-				 figsize[1] * dpi)
+	self.figwidth = figsize[0] * dpi
+	self.figheight = figsize[1] * dpi
+	self.bbox = Bbox.from_lbwh(0, 0, self.figwidth, self.figheight)
 	
 self.frameon = frameon
 
@@ -324,11 +324,16 @@
 w,h = args[0]
 else:
 w,h = args
- self.figwidth.set(w)
- self.figheight.set(h)
 
+	
+ self.figwidth = w
+ self.figheight = h
+ # self.figwidth.set(w) MGDTODO
+ # self.figheight.set(h)
+	
 if forward:
- dpival = self.dpi.get()
+ # dpival = self.dpi.get()
+ dpival = self.dpi
 canvasw = w*dpival
 canvash = h*dpival
 manager = getattr(self.canvas, 'manager', None)
@@ -336,7 +341,8 @@
 manager.resize(int(canvasw), int(canvash))
 
 def get_size_inches(self):
- return self.figwidth.get(), self.figheight.get()
+ return self.figwidth, self.figheight
+ # return self.figwidth.get(), self.figheight.get() MGDTODO
 
 def get_edgecolor(self):
 'Get the edge color of the Figure rectangle'
@@ -348,7 +354,8 @@
 
 def get_figwidth(self):
 'Return the figwidth as a float'
- return self.figwidth.get()
+	return self.figwidth
+ # return self.figwidth.get() MGDTODO
 
 def get_figheight(self):
 'Return the figheight as a float'
@@ -356,7 +363,8 @@
 
 def get_dpi(self):
 'Return the dpi as a float'
- return self.dpi.get()
+ return self.dpi
+ # return self.dpi.get() MGDTODO
 
 def get_frameon(self):
 'get the boolean indicating frameon'
@@ -384,7 +392,8 @@
 
 ACCEPTS: float
 """
- self.dpi.set(val)
+ # self.dpi.set(val) MGDTODO
+	self.dpi = val
 
 def set_figwidth(self, val):
 """
@@ -392,15 +401,17 @@
 
 ACCEPTS: float
 """
- self.figwidth.set(val)
-
+ # self.figwidth.set(val) MGDTODO
+ self.figwidth = val
+	
 def set_figheight(self, val):
 """
 Set the height of the figure in inches
 
 ACCEPTS: float
 """
- self.figheight.set(val)
+	# MGDTODO (set())
+ self.figheight = val
 
 def set_frameon(self, b):
 """
Modified: branches/transforms/lib/matplotlib/lines.py
===================================================================
--- branches/transforms/lib/matplotlib/lines.py	2007年09月11日 12:46:27 UTC (rev 3829)
+++ branches/transforms/lib/matplotlib/lines.py	2007年09月11日 17:56:13 UTC (rev 3830)
@@ -18,7 +18,7 @@
 from cbook import iterable, is_string_like, is_numlike
 from colors import colorConverter
 
-from bbox import lbwh_to_bbox
+from bbox import Bbox
 from matplotlib import rcParams
 
 # special-purpose marker identifiers:
@@ -368,6 +368,7 @@
 	a = npy.vstack((x, y)).swapaxes(0, 1)
 	####
 x, y = self.get_transform()(a)
+	print "get_window_extent", self.get_transform()
 	
 #x, y = self.get_transform().seq_x_y(x, y)
 
@@ -384,10 +385,11 @@
 bottom -= ms/2
 width += ms
 height += ms
- return lbwh_to_bbox(left, bottom, width, height)
+ return Bbox.from_lbwh(left, bottom, width, height)
 
 
 def set_axes(self, ax):
+	print "set_axes"
 Artist.set_axes(self, ax)
 if ax.xaxis is not None:
 self._xcid = ax.xaxis.callbacks.connect('units', self.recache)
Modified: branches/transforms/lib/matplotlib/patches.py
===================================================================
--- branches/transforms/lib/matplotlib/patches.py	2007年09月11日 12:46:27 UTC (rev 3829)
+++ branches/transforms/lib/matplotlib/patches.py	2007年09月11日 17:56:13 UTC (rev 3830)
@@ -212,7 +212,7 @@
 tverts = self.get_transform()(verts)
 
 	# MGDTODO: This result is an Nx2 numpy array, which could be passed
-	# directly to renderer.draw_polygon. However, it currently expects
+	# directly to renderer.draw_polygon since it currently expects
 	# a list of tuples so we're converting it to that now.
 	tverts = [tuple(x) for x in tverts]
 	
Modified: branches/transforms/lib/matplotlib/text.py
===================================================================
--- branches/transforms/lib/matplotlib/text.py	2007年09月11日 12:46:27 UTC (rev 3829)
+++ branches/transforms/lib/matplotlib/text.py	2007年09月11日 17:56:13 UTC (rev 3830)
@@ -15,7 +15,7 @@
 from cbook import enumerate, is_string_like, maxdict, is_numlike
 from font_manager import FontProperties
 from patches import bbox_artist, YAArrow
-from bbox import lbwh_to_bbox, bbox_union
+from bbox import Bbox, bbox_union
 from lines import Line2D
 
 import matplotlib.nxutils as nxutils
@@ -40,8 +40,6 @@
 angle = float(rotation)
 return angle%360
 
-_unit_box = lbwh_to_bbox(0,0,1,1)
-
 # these are not available for the object inspector until after the
 # class is build so we define an initial set here for the init
 # function and they will be overridden after object defn
@@ -264,7 +262,7 @@
 ymin += offsety
 ymax += offsety
 
- bbox = lbwh_to_bbox(xmin, ymin, width, height)
+ bbox = Bbox.from_lbwh(xmin, ymin, width, height)
 
 
 # now rotate the positions around the first x,y position
@@ -423,10 +421,10 @@
 
 def get_window_extent(self, renderer=None):
 #return _unit_box
- if not self.get_visible(): return _unit_box
+ if not self.get_visible(): return Bbox.unit()
 if self._text == '':
 tx, ty = self._get_xy_display()
- return lbwh_to_bbox(tx,ty,0,0)
+ return Bbox.from_lbwh(tx,ty,0,0)
 
 if renderer is not None:
 self._renderer = renderer
Modified: branches/transforms/src/_backend_agg.cpp
===================================================================
--- branches/transforms/src/_backend_agg.cpp	2007年09月11日 12:46:27 UTC (rev 3829)
+++ branches/transforms/src/_backend_agg.cpp	2007年09月11日 17:56:13 UTC (rev 3830)
@@ -56,7 +56,7 @@
 throw Py::ValueError("Transformation matrix must be given as a 6-element list.");
 }
 
- agg::trans_affine xytrans = agg::trans_affine
+ return agg::trans_affine
 (Py::Float(seq[0]), 
 Py::Float(seq[1]), 
 Py::Float(seq[2]), 
@@ -1935,18 +1935,8 @@
 if (ya==NULL)
 throw Py::TypeError("RendererAgg::_draw_markers_cache expected numerix array");
 
- Transformation* mpltransform = static_cast<Transformation*>(args[5].ptr());
+ agg::trans_affine xytrans = py_sequence_to_agg_transformation_matrix(args[5]);
 
- double a, b, c, d, tx, ty;
- try {
- mpltransform->affine_params_api(&a, &b, &c, &d, &tx, &ty);
- }
- catch(...) {
- throw Py::ValueError("Domain error on affine_params_api in RendererAgg::_draw_markers_cache");
- }
- 
- agg::trans_affine xytrans = agg::trans_affine(a,b,c,d,tx,ty);
- 
 size_t Nx = xa->dimensions[0];
 size_t Ny = ya->dimensions[0];
 
@@ -2006,15 +1996,16 @@
 for (size_t i=0; i<Nx; i++) {
 thisx = *(double *)(xa->data + i*xa->strides[0]);
 thisy = *(double *)(ya->data + i*ya->strides[0]);
+
+ // MGDTODO
+// if (mpltransform->need_nonlinear_api())
+// try {
+// 	mpltransform->nonlinear_only_api(&thisx, &thisy);
+// }
+// catch(...) {
+// 	continue;
+// }
 
- if (mpltransform->need_nonlinear_api())
- try {
-	mpltransform->nonlinear_only_api(&thisx, &thisy);
- }
- catch(...) {
-	continue;
- }
- 
 xytrans.transform(&thisx, &thisy);
 
 thisy = heightd - thisy; //flipy
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
From: <md...@us...> - 2007年09月11日 17:57:48
Revision: 3831
 http://matplotlib.svn.sourceforge.net/matplotlib/?rev=3831&view=rev
Author: mdboom
Date: 2007年09月11日 10:57:47 -0700 (2007年9月11日)
Log Message:
-----------
Merged revisions 3824-3830 via svnmerge from 
http://matplotlib.svn.sf.net/svnroot/matplotlib/trunk/matplotlib
........
 r3825 | pkienzle | 2007年09月10日 14:45:32 -0400 (2007年9月10日) | 1 line
 
 Windows needs binary open flag for font files
........
 r3827 | jouni | 2007年09月10日 16:31:01 -0400 (2007年9月10日) | 2 lines
 
 Better bounding boxes for pdf usetex, including descents.
........
 r3828 | jouni | 2007年09月10日 16:55:29 -0400 (2007年9月10日) | 2 lines
 
 Bugfixes in pdf usetex
........
 r3829 | mdboom | 2007年09月11日 08:46:27 -0400 (2007年9月11日) | 3 lines
 
 Fix bug in PDF clip routine that resulted in the cryptic error message
 "There are too many arguments" in Adobe Acrobat.
........
Modified Paths:
--------------
 branches/transforms/lib/matplotlib/backends/backend_pdf.py
 branches/transforms/lib/matplotlib/dviread.py
 branches/transforms/ttconv/pprdrv_tt.cpp
Property Changed:
----------------
 branches/transforms/
Property changes on: branches/transforms
___________________________________________________________________
Name: svnmerge-integrated
 - /trunk/matplotlib:1-3823
 + /trunk/matplotlib:1-3830
Modified: branches/transforms/lib/matplotlib/backends/backend_pdf.py
===================================================================
--- branches/transforms/lib/matplotlib/backends/backend_pdf.py	2007年09月11日 17:56:13 UTC (rev 3830)
+++ branches/transforms/lib/matplotlib/backends/backend_pdf.py	2007年09月11日 17:57:47 UTC (rev 3831)
@@ -519,12 +519,13 @@
 ul_position, ul_thickness = font.get_ps_font_info()
 
 if fontinfo.encodingfile is not None:
- differencesArray = [ Name(ch) for ch in 
- dviread.Encoding(fontinfo.encodingfile) ]
+ enc = dviread.Encoding(fontinfo.encodingfile)
+ widths = [ afmdata.get_width_from_char_name(ch)
+ for ch in enc ]
+ differencesArray = [ Name(ch) for ch in enc ]
 differencesArray = [ 0 ] + differencesArray
 firstchar = 0
 lastchar = len(differencesArray) - 2
- widths = [ 100 for x in range(firstchar,lastchar+1) ] # XXX TODO
 else:
 widths = [ None for i in range(256) ]
 for ch in range(256):
@@ -1434,7 +1435,7 @@
 fontsize = prop.get_size_in_points()
 dvifile = texmanager.make_dvi(s, fontsize)
 dvi = dviread.Dvi(dvifile, 72)
- text, boxes = iter(dvi).next()
+ page = iter(dvi).next()
 dvi.close()
 
 if angle == 0: # avoid rounding errors in common case
@@ -1448,7 +1449,7 @@
 # Gather font information and do some setup for combining
 # characters into strings.
 oldfontnum, seq = None, []
- for x1, y1, fontnum, glyph, width in text:
+ for x1, y1, fontnum, glyph, width in page.text:
 if fontnum != oldfontnum:
 texname, fontsize = dvi.fontinfo(fontnum)
 fontinfo = self.tex_font_mapping(texname)
@@ -1462,8 +1463,8 @@
 seq += [('end',)]
 
 # Find consecutive text strings with constant x coordinate and
- # combine into one string (if needed kern would be less than
- # 0.1 points) or several strings interspersed with kerns.
+ # combine into a sequence of strings and kerns, or just one
+ # string (if any kerns would be less than 0.1 points).
 i, curx = 0, 0
 while i < len(seq)-1:
 elt, next = seq[i:i+2]
@@ -1503,7 +1504,7 @@
 boxgc = self.new_gc()
 boxgc.copy_properties(gc)
 boxgc.set_linewidth(0)
- for x1, y1, h, w in boxes:
+ for x1, y1, h, w in page.boxes:
 (x1, y1), (x2, y2), (x3, y3), (x4, y4) = \
 mytrans(x1, y1), mytrans(x1+w, y1), \
 mytrans(x1+w, y1+h), mytrans(x1, y1+h)
@@ -1653,14 +1654,9 @@
 fontsize = prop.get_size_in_points()
 dvifile = texmanager.make_dvi(s, fontsize)
 dvi = dviread.Dvi(dvifile, 72)
- text, boxes = iter(dvi).next()
- # TODO: better bounding box -- this is not quite right:
- l = min(p[0] for p in text+boxes)
- r = max(p[0] for p in text+boxes) + fontsize
- b = min(p[1] for p in text+boxes)
- t = max(p[1] for p in text+boxes) + fontsize
- # (not to even mention finding the baseline)
- return r-l, t-b, t-b
+ page = iter(dvi).next()
+ dvi.close()
+ return page.width, page.height, page.descent
 if ismath:
 w, h, d, glyphs, rects, used_characters = \
 self.mathtext_parser.parse(s, 72, prop)
@@ -1837,7 +1833,7 @@
 cmds.extend(self.pop())
 # Unless we hit the right one, set the clip polygon
 if (self._cliprect, self._clippath) != (cliprect, clippath):
- cmds.append(self.push())
+ cmds.extend(self.push())
 if self._cliprect != cliprect:
 cmds.extend([t for t in cliprect] + 
 [Op.rectangle, Op.clip, Op.endpath])
Modified: branches/transforms/lib/matplotlib/dviread.py
===================================================================
--- branches/transforms/lib/matplotlib/dviread.py	2007年09月11日 17:56:13 UTC (rev 3830)
+++ branches/transforms/lib/matplotlib/dviread.py	2007年09月11日 17:57:47 UTC (rev 3831)
@@ -6,19 +6,21 @@
 Interface:
 
 dvi = Dvi(filename, 72)
- for text, boxes in dvi: # iterate over pages
- text, boxes = dvi.output(72)
- for x,y,font,glyph,width in text:
+ for page in dvi: # iterate over pages
+ w, h, d = page.width, page.height, page.descent
+ for x,y,font,glyph,width in page.text:
 fontname, pointsize = dvi.fontinfo(font)
 ...
- for x,y,height,width in boxes:
+ for x,y,height,width in page.boxes:
 ...
 """
 
-# TODO: support for TeX virtual fonts (*.vf) which are a dvi-like format
+# TODO: support TeX virtual fonts (*.vf) which are a sort of
+# subroutine collections for dvi files
 
 import matplotlib
 import matplotlib.cbook as mpl_cbook
+import numpy as npy
 import os
 import struct
 
@@ -74,21 +76,34 @@
 def _output(self):
 """
 Output the text and boxes belonging to the most recent page.
- text, boxes = dvi._output()
+ page = dvi._output()
 """
- t0 = self.text[0]
- minx, miny, maxx, maxy = t0[0], t0[1], t0[0], t0[1]
+ minx, miny, maxx, maxy = npy.inf, npy.inf, -npy.inf, -npy.inf
+ maxy_pure = -npy.inf
 for elt in self.text + self.boxes:
- x,y = elt[:2]
- if x < minx: minx = x
- if y < miny: miny = y
- if x > maxx: maxx = x
- if y > maxy: maxy = y
+ if len(elt) == 4: # box
+ x,y,h,w = elt
+ e = 0 # zero depth
+ else: # glyph
+ x,y,f,g,w = elt
+ font = self.fonts[f]
+ h = (font.scale * font.tfm.height[g]) >> 20
+ e = (font.scale * font.tfm.depth[g]) >> 20
+ minx = min(minx, x)
+ miny = min(miny, y - h)
+ maxx = max(maxx, x + w)
+ maxy = max(maxy, y + e)
+ maxy_pure = max(maxy_pure, y)
+
 d = self.dpi / (72.27 * 2**16) # from TeX's "scaled points" to dpi units
 text = [ ((x-minx)*d, (maxy-y)*d, f, g, w*d) for (x,y,f,g,w) in self.text ]
 boxes = [ ((x-minx)*d, (maxy-y)*d, h*d, w*d) for (x,y,h,w) in self.boxes ]
- return text, boxes
 
+ return mpl_cbook.Bunch(text=text, boxes=boxes, 
+ width=(maxx-minx)*d, 
+ height=(maxy_pure-miny)*d, 
+ descent=(maxy-maxy_pure)*d)
+
 def fontinfo(self, f):
 """
 texname, pointsize = dvi.fontinfo(fontnum)
@@ -361,6 +376,7 @@
 width[i]: width of character #i, needs to be scaled 
 by the factor specified in the dvi file
 (this is a dict because indexing may not start from 0)
+ height[i], depth[i]: height and depth of character #i
 """
 
 def __init__(self, filename):
@@ -368,22 +384,29 @@
 
 try:
 header1 = file.read(24)
- lh, bc, ec, nw = \
- struct.unpack('!4H', header1[2:10])
+ lh, bc, ec, nw, nh, nd = \
+ struct.unpack('!6H', header1[2:14])
 header2 = file.read(4*lh)
 self.checksum, self.design_size = \
 struct.unpack('!2I', header2[:8])
 # there is also encoding information etc.
 char_info = file.read(4*(ec-bc+1))
 widths = file.read(4*nw)
+ heights = file.read(4*nh)
+ depths = file.read(4*nd)
 finally:
 file.close()
 
- widths = struct.unpack('!%dI' % nw, widths)
- self.width = {}
+ self.width, self.height, self.depth = {}, {}, {}
+ widths, heights, depths = \
+ [ struct.unpack('!%dI' % n, x) 
+ for n,x in [(nw, widths), (nh, heights), (nd, depths)] ]
 for i in range(ec-bc):
 self.width[bc+i] = widths[ord(char_info[4*i])]
+ self.height[bc+i] = heights[ord(char_info[4*i+1]) >> 4]
+ self.depth[bc+i] = depths[ord(char_info[4*i+1]) & 0xf]
 
+
 class PsfontsMap(object):
 """
 A psfonts.map formatted file, mapping TeX fonts to PS fonts.
Modified: branches/transforms/ttconv/pprdrv_tt.cpp
===================================================================
--- branches/transforms/ttconv/pprdrv_tt.cpp	2007年09月11日 17:56:13 UTC (rev 3830)
+++ branches/transforms/ttconv/pprdrv_tt.cpp	2007年09月11日 17:57:47 UTC (rev 3831)
@@ -1088,7 +1088,7 @@
 font.filename=filename;
 
 /* Open the font file */
- if( (font.file = fopen(filename,"r")) == (FILE*)NULL )
+ if( (font.file = fopen(filename,"rb")) == (FILE*)NULL )
 	throw TTException("Failed to open TrueType font");
 
 /* Allocate space for the unvarying part of the offset table. */
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
From: <md...@us...> - 2007年09月12日 14:05:25
Revision: 3836
 http://matplotlib.svn.sourceforge.net/matplotlib/?rev=3836&view=rev
Author: mdboom
Date: 2007年09月12日 07:05:20 -0700 (2007年9月12日)
Log Message:
-----------
Merged revisions 3831-3835 via svnmerge from 
http://matplotlib.svn.sf.net/svnroot/matplotlib/trunk/matplotlib
........
 r3832 | dsdale | 2007年09月11日 14:46:47 -0400 (2007年9月11日) | 3 lines
 
 removed MANIFEST from revision control. It is generated by MANIFEST.in 
 when building source distribution archives
........
 r3833 | jrevans | 2007年09月11日 15:40:27 -0400 (2007年9月11日) | 5 lines
 
 Added the ability for the following in the various GUI backends:
 >>> import pylab
 >>> fig = pylab.figure()
 >>> fig.canvas.set_window_title("My Plot Window")
........
 r3834 | jouni | 2007年09月12日 03:04:38 -0400 (2007年9月12日) | 3 lines
 
 Further development of dviread. It now attempts to read virtual fonts,
 but the positioning is still somewhat off.
........
Modified Paths:
--------------
 branches/transforms/lib/matplotlib/backend_bases.py
 branches/transforms/lib/matplotlib/backends/backend_fltkagg.py
 branches/transforms/lib/matplotlib/backends/backend_gtk.py
 branches/transforms/lib/matplotlib/backends/backend_pdf.py
 branches/transforms/lib/matplotlib/backends/backend_qt.py
 branches/transforms/lib/matplotlib/backends/backend_qt4.py
 branches/transforms/lib/matplotlib/backends/backend_tkagg.py
 branches/transforms/lib/matplotlib/backends/backend_wx.py
 branches/transforms/lib/matplotlib/dviread.py
Removed Paths:
-------------
 branches/transforms/MANIFEST
Property Changed:
----------------
 branches/transforms/
Property changes on: branches/transforms
___________________________________________________________________
Name: svnmerge-integrated
 - /trunk/matplotlib:1-3830
 + /trunk/matplotlib:1-3835
Deleted: branches/transforms/MANIFEST
===================================================================
--- branches/transforms/MANIFEST	2007年09月12日 13:36:25 UTC (rev 3835)
+++ branches/transforms/MANIFEST	2007年09月12日 14:05:20 UTC (rev 3836)
@@ -1,1398 +0,0 @@
-API_CHANGES
-CHANGELOG
-INSTALL
-INTERACTIVE
-KNOWN_BUGS
-MANIFEST.in
-Makefile
-NUMARRAY_ISSUES
-README
-TODO
-__init__.py
-makeswig.py
-matplotlibrc.template
-setup.cfg
-setup.py
-setupegg.py
-setupext.py
-CXX/Config.hxx
-CXX/Exception.hxx
-CXX/Extensions.hxx
-CXX/IndirectPythonInterface.cxx
-CXX/IndirectPythonInterface.hxx
-CXX/Objects.hxx
-CXX/Version.hxx
-CXX/cxx_extensions.cxx
-CXX/cxxextensions.c
-CXX/cxxsupport.cxx
-agg23/font_freetype/Makefile.am
-agg23/font_freetype/agg_font_freetype.cpp
-agg23/font_freetype/agg_font_freetype.h
-agg23/font_win32_tt/agg_font_win32_tt.cpp
-agg23/font_win32_tt/agg_font_win32_tt.h
-agg23/include/Makefile.am
-agg23/include/agg_alpha_mask_u8.h
-agg23/include/agg_arc.h
-agg23/include/agg_array.h
-agg23/include/agg_arrowhead.h
-agg23/include/agg_basics.h
-agg23/include/agg_bezier_arc.h
-agg23/include/agg_bitset_iterator.h
-agg23/include/agg_bounding_rect.h
-agg23/include/agg_bspline.h
-agg23/include/agg_clip_liang_barsky.h
-agg23/include/agg_color_gray.h
-agg23/include/agg_color_rgba.h
-agg23/include/agg_config.h
-agg23/include/agg_conv_adaptor_vcgen.h
-agg23/include/agg_conv_adaptor_vpgen.h
-agg23/include/agg_conv_bspline.h
-agg23/include/agg_conv_clip_polygon.h
-agg23/include/agg_conv_clip_polyline.h
-agg23/include/agg_conv_close_polygon.h
-agg23/include/agg_conv_concat.h
-agg23/include/agg_conv_contour.h
-agg23/include/agg_conv_curve.h
-agg23/include/agg_conv_dash.h
-agg23/include/agg_conv_gpc.h
-agg23/include/agg_conv_marker.h
-agg23/include/agg_conv_marker_adaptor.h
-agg23/include/agg_conv_segmentator.h
-agg23/include/agg_conv_shorten_path.h
-agg23/include/agg_conv_smooth_poly1.h
-agg23/include/agg_conv_stroke.h
-agg23/include/agg_conv_transform.h
-agg23/include/agg_conv_unclose_polygon.h
-agg23/include/agg_curves.h
-agg23/include/agg_dda_line.h
-agg23/include/agg_ellipse.h
-agg23/include/agg_ellipse_bresenham.h
-agg23/include/agg_embedded_raster_fonts.h
-agg23/include/agg_font_cache_manager.h
-agg23/include/agg_gamma_functions.h
-agg23/include/agg_gamma_lut.h
-agg23/include/agg_glyph_raster_bin.h
-agg23/include/agg_gsv_text.h
-agg23/include/agg_image_filters.h
-agg23/include/agg_line_aa_basics.h
-agg23/include/agg_math.h
-agg23/include/agg_math_stroke.h
-agg23/include/agg_path_storage.h
-agg23/include/agg_path_storage_integer.h
-agg23/include/agg_pattern_filters_rgba.h
-agg23/include/agg_pixfmt_amask_adaptor.h
-agg23/include/agg_pixfmt_gray.h
-agg23/include/agg_pixfmt_rgb.h
-agg23/include/agg_pixfmt_rgb_packed.h
-agg23/include/agg_pixfmt_rgba.h
-agg23/include/agg_rasterizer_outline.h
-agg23/include/agg_rasterizer_outline_aa.h
-agg23/include/agg_rasterizer_scanline_aa.h
-agg23/include/agg_render_scanlines.h
-agg23/include/agg_renderer_base.h
-agg23/include/agg_renderer_markers.h
-agg23/include/agg_renderer_mclip.h
-agg23/include/agg_renderer_outline_aa.h
-agg23/include/agg_renderer_outline_image.h
-agg23/include/agg_renderer_primitives.h
-agg23/include/agg_renderer_raster_text.h
-agg23/include/agg_renderer_scanline.h
-agg23/include/agg_rendering_buffer.h
-agg23/include/agg_rendering_buffer_dynarow.h
-agg23/include/agg_rounded_rect.h
-agg23/include/agg_scanline_bin.h
-agg23/include/agg_scanline_boolean_algebra.h
-agg23/include/agg_scanline_p.h
-agg23/include/agg_scanline_storage_aa.h
-agg23/include/agg_scanline_storage_bin.h
-agg23/include/agg_scanline_u.h
-agg23/include/agg_shorten_path.h
-agg23/include/agg_simul_eq.h
-agg23/include/agg_span_allocator.h
-agg23/include/agg_span_converter.h
-agg23/include/agg_span_generator.h
-agg23/include/agg_span_gouraud.h
-agg23/include/agg_span_gouraud_gray.h
-agg23/include/agg_span_gouraud_rgba.h
-agg23/include/agg_span_gradient.h
-agg23/include/agg_span_gradient_alpha.h
-agg23/include/agg_span_image_filter.h
-agg23/include/agg_span_image_filter_gray.h
-agg23/include/agg_span_image_filter_rgb.h
-agg23/include/agg_span_image_filter_rgba.h
-agg23/include/agg_span_image_resample.h
-agg23/include/agg_span_image_resample_gray.h
-agg23/include/agg_span_image_resample_rgb.h
-agg23/include/agg_span_image_resample_rgba.h
-agg23/include/agg_span_interpolator_adaptor.h
-agg23/include/agg_span_interpolator_linear.h
-agg23/include/agg_span_interpolator_persp.h
-agg23/include/agg_span_interpolator_trans.h
-agg23/include/agg_span_pattern.h
-agg23/include/agg_span_pattern_filter_gray.h
-agg23/include/agg_span_pattern_filter_rgb.h
-agg23/include/agg_span_pattern_filter_rgba.h
-agg23/include/agg_span_pattern_resample_gray.h
-agg23/include/agg_span_pattern_resample_rgb.h
-agg23/include/agg_span_pattern_resample_rgba.h
-agg23/include/agg_span_pattern_rgb.h
-agg23/include/agg_span_pattern_rgba.h
-agg23/include/agg_span_solid.h
-agg23/include/agg_span_subdiv_adaptor.h
-agg23/include/agg_trans_affine.h
-agg23/include/agg_trans_bilinear.h
-agg23/include/agg_trans_double_path.h
-agg23/include/agg_trans_lens.h
-agg23/include/agg_trans_perspective.h
-agg23/include/agg_trans_single_path.h
-agg23/include/agg_trans_viewport.h
-agg23/include/agg_trans_warp_magnifier.h
-agg23/include/agg_vcgen_bspline.h
-agg23/include/agg_vcgen_contour.h
-agg23/include/agg_vcgen_dash.h
-agg23/include/agg_vcgen_markers_term.h
-agg23/include/agg_vcgen_smooth_poly1.h
-agg23/include/agg_vcgen_stroke.h
-agg23/include/agg_vcgen_vertex_sequence.h
-agg23/include/agg_vertex_sequence.h
-agg23/include/agg_vpgen_clip_polygon.h
-agg23/include/agg_vpgen_clip_polyline.h
-agg23/include/agg_vpgen_segmentator.h
-agg23/include/ctrl/Makefile.am
-agg23/include/ctrl/agg_bezier_ctrl.h
-agg23/include/ctrl/agg_cbox_ctrl.h
-agg23/include/ctrl/agg_ctrl.h
-agg23/include/ctrl/agg_gamma_ctrl.h
-agg23/include/ctrl/agg_gamma_spline.h
-agg23/include/ctrl/agg_polygon_ctrl.h
-agg23/include/ctrl/agg_rbox_ctrl.h
-agg23/include/ctrl/agg_scale_ctrl.h
-agg23/include/ctrl/agg_slider_ctrl.h
-agg23/include/ctrl/agg_spline_ctrl.h
-agg23/include/platform/Makefile.am
-agg23/include/platform/agg_platform_support.h
-agg23/include/platform/mac/agg_mac_pmap.h
-agg23/include/platform/win32/agg_win32_bmp.h
-agg23/include/util/Makefile.am
-agg23/include/util/agg_color_conv.h
-agg23/include/util/agg_color_conv_rgb16.h
-agg23/include/util/agg_color_conv_rgb8.h
-agg23/src/ChangeLog
-agg23/src/Makefile
-agg23/src/Makefile.am
-agg23/src/agg_arc.cpp
-agg23/src/agg_arrowhead.cpp
-agg23/src/agg_bezier_arc.cpp
-agg23/src/agg_bspline.cpp
-agg23/src/agg_curves.cpp
-agg23/src/agg_embedded_raster_fonts.cpp
-agg23/src/agg_gsv_text.cpp
-agg23/src/agg_image_filters.cpp
-agg23/src/agg_line_aa_basics.cpp
-agg23/src/agg_line_profile_aa.cpp
-agg23/src/agg_path_storage.cpp
-agg23/src/agg_rasterizer_scanline_aa.cpp
-agg23/src/agg_rounded_rect.cpp
-agg23/src/agg_sqrt_tables.cpp
-agg23/src/agg_trans_affine.cpp
-agg23/src/agg_trans_double_path.cpp
-agg23/src/agg_trans_single_path.cpp
-agg23/src/agg_trans_warp_magnifier.cpp
-agg23/src/agg_vcgen_bspline.cpp
-agg23/src/agg_vcgen_contour.cpp
-agg23/src/agg_vcgen_dash.cpp
-agg23/src/agg_vcgen_markers_term.cpp
-agg23/src/agg_vcgen_smooth_poly1.cpp
-agg23/src/agg_vcgen_stroke.cpp
-agg23/src/agg_vpgen_clip_polygon.cpp
-agg23/src/agg_vpgen_clip_polyline.cpp
-agg23/src/agg_vpgen_segmentator.cpp
-agg23/src/authors
-agg23/src/autogen.sh
-agg23/src/configure.in
-agg23/src/copying
-agg23/src/install
-agg23/src/news
-agg23/src/readme
-agg23/src/ctrl/Makefile.am
-agg23/src/ctrl/agg_bezier_ctrl.cpp
-agg23/src/ctrl/agg_cbox_ctrl.cpp
-agg23/src/ctrl/agg_gamma_ctrl.cpp
-agg23/src/ctrl/agg_gamma_spline.cpp
-agg23/src/ctrl/agg_polygon_ctrl.cpp
-agg23/src/ctrl/agg_rbox_ctrl.cpp
-agg23/src/ctrl/agg_scale_ctrl.cpp
-agg23/src/ctrl/agg_slider_ctrl.cpp
-agg23/src/ctrl/agg_spline_ctrl.cpp
-agg23/src/platform/Makefile.am
-agg23/src/platform/AmigaOS/agg_platform_support.cpp
-agg23/src/platform/BeOS/agg_platform_support.cpp
-agg23/src/platform/X11/Makefile.am
-agg23/src/platform/X11/agg_platform_support.cpp
-agg23/src/platform/mac/agg_mac_pmap.cpp
-agg23/src/platform/mac/agg_platform_support.cpp
-agg23/src/platform/sdl/agg_platform_support.cpp
-agg23/src/platform/win32/agg_platform_support.cpp
-agg23/src/platform/win32/agg_win32_bmp.cpp
-agg23/svg/agg_svg_exception.h
-agg23/svg/agg_svg_parser.cpp
-agg23/svg/agg_svg_parser.h
-agg23/svg/agg_svg_path_renderer.cpp
-agg23/svg/agg_svg_path_renderer.h
-agg23/svg/agg_svg_path_tokenizer.cpp
-agg23/svg/agg_svg_path_tokenizer.h
-agg23/svg/svg_test.cpp
-agg23/svg/BeOS/Makefile
-agg23/svg/X11/Makefile
-agg23/svg/macos_cw/expat.h
-agg23/svg/macos_cw/include.h
-agg23/svg/macos_cw/xmlparse.h
-agg23/svg/win32_api/Makefile
-agg23/svg/win32_api/svg_test.dsp
-agg23/svg/win32_api/svg_test.dsw
-examples/README
-examples/__init__.py
-examples/accented_text.py
-examples/agg_oo.py
-examples/agg_resize.py
-examples/agg_test.py
-examples/alignment_test.py
-examples/anim.py
-examples/anim_tk.py
-examples/animation_blit.py
-examples/animation_blit_fltk.py
-examples/animation_blit_qt.py
-examples/animation_blit_qt4.py
-examples/animation_blit_tk.py
-examples/animation_blit_wx.py
-examples/annotation_demo.py
-examples/anscombe.py
-examples/arctest.py
-examples/arrow_demo.py
-examples/axes_demo.py
-examples/axes_props.py
-examples/axhspan_demo.py
-examples/axis_equal_demo.py
-examples/backend_driver.py
-examples/bar_stacked.py
-examples/barchart_demo.py
-examples/barcode_demo.py
-examples/barh_demo.py
-examples/boxplot_demo.py
-examples/break.py
-examples/broken_barh.py
-examples/clippath_test.py
-examples/clippedline.py
-examples/collections_demo.py
-examples/color_by_yvalue.py
-examples/color_demo.py
-examples/colours.py
-examples/contour_demo.py
-examples/contour_image.py
-examples/contourf_demo.py
-examples/coords_demo.py
-examples/coords_report.py
-examples/csd_demo.py
-examples/cursor_demo.py
-examples/custom_figure_class.py
-examples/custom_ticker1.py
-examples/customize_rc.py
-examples/dannys_example.py
-examples/dash_control.py
-examples/dashpointlabel.py
-examples/dashtick.py
-examples/data_helper.py
-examples/date_demo1.py
-examples/date_demo2.py
-examples/date_demo_convert.py
-examples/date_demo_rrule.py
-examples/dynamic_collection.py
-examples/dynamic_demo.py
-examples/dynamic_demo_wx.py
-examples/dynamic_image_gtkagg.py
-examples/dynamic_image_wxagg.py
-examples/dynamic_image_wxagg2.py
-examples/ellipse_demo.py
-examples/ellipse_rotated.py
-examples/embedding_in_gtk.py
-examples/embedding_in_gtk2.py
-examples/embedding_in_gtk3.py
-examples/embedding_in_qt.py
-examples/embedding_in_qt4.py
-examples/embedding_in_tk.py
-examples/embedding_in_tk2.py
-examples/embedding_in_wx.py
-examples/embedding_in_wx2.py
-examples/embedding_in_wx3.py
-examples/embedding_in_wx4.py
-examples/errorbar_demo.py
-examples/figimage_demo.py
-examples/figlegend_demo.py
-examples/figtext.py
-examples/fill_between.py
-examples/fill_between_posneg.py
-examples/fill_demo.py
-examples/fill_demo2.py
-examples/fill_spiral.py
-examples/finance_demo.py
-examples/font_indexing.py
-examples/font_table_ttf.py
-examples/fonts_demo.py
-examples/fonts_demo_kw.py
-examples/ftface_props.py
-examples/ganged_plots.py
-examples/gdtest.py
-examples/glyph_to_path.py
-examples/gtk_spreadsheet.py
-examples/hatch_demo.py
-examples/histogram_demo.py
-examples/histogram_demo_canvasagg.py
-examples/image_demo.py
-examples/image_demo2.py
-examples/image_demo3.py
-examples/image_demo_na.py
-examples/image_interp.py
-examples/image_masked.py
-examples/image_origin.py
-examples/integral_demo.py
-examples/interactive.py
-examples/interactive2.py
-examples/interp_demo.py
-examples/invert_axes.py
-examples/keypress_demo.py
-examples/lasso_demo.py
-examples/layer_images.py
-examples/legend_auto.py
-examples/legend_demo.py
-examples/legend_demo2.py
-examples/legend_scatter.py
-examples/line_collection.py
-examples/line_collection2.py
-examples/line_styles.py
-examples/load_converter.py
-examples/log_bar.py
-examples/log_demo.py
-examples/log_test.py
-examples/logo.py
-examples/major_minor_demo1.py
-examples/major_minor_demo2.py
-examples/masked_demo.py
-examples/mathtext2_demo.py
-examples/mathtext_demo.py
-examples/matplotlib_icon.py
-examples/matshow.py
-examples/movie_demo.py
-examples/mpl_with_glade.py
-examples/mri_demo.py
-examples/mri_with_eeg.py
-examples/multi_image.py
-examples/multiline.py
-examples/multiple_figs_demo.py
-examples/newscalarformatter_demo.py
-examples/object_picker.py
-examples/pcolor_demo.py
-examples/pcolor_demo2.py
-examples/pcolor_log.py
-examples/pcolor_nonuniform.py
-examples/pcolor_small.py
-examples/pick_event_demo.py
-examples/picker_demo.py
-examples/pie_demo.py
-examples/polar_bar.py
-examples/polar_demo.py
-examples/polar_legend.py
-examples/polar_scatter.py
-examples/poly_editor.py
-examples/poormans_contour.py
-examples/print_stdout.py
-examples/printing_in_wx.py
-examples/psd_demo.py
-examples/pstest.py
-examples/pylab_with_gtk.py
-examples/pythonic_matplotlib.py
-examples/quadmesh_demo.py
-examples/quiver_demo.py
-examples/scatter_custom_symbol.py
-examples/scatter_demo.py
-examples/scatter_demo2.py
-examples/scatter_masked.py
-examples/scatter_profile.py
-examples/scatter_star_poly.py
-examples/set_and_get.py
-examples/shared_axis_demo.py
-examples/simple3d.py
-examples/simple3d_oo.py
-examples/simple_plot.py
-examples/specgram_demo.py
-examples/spy_demos.py
-examples/stem_plot.py
-examples/stock_demo.py
-examples/strip_chart_demo.py
-examples/subplot_demo.py
-examples/subplot_toolbar.py
-examples/subplots_adjust.py
-examples/system_monitor.py
-examples/table_demo.py
-examples/tex_demo.py
-examples/text_handles.py
-examples/text_rotation.py
-examples/text_themes.py
-examples/to_numeric.py
-examples/toggle_images.py
-examples/transoffset.py
-examples/two_scales.py
-examples/unicode_demo.py
-examples/vertical_ticklabels.py
-examples/vline_demo.py
-examples/webapp_demo.py
-examples/wxcursor_demo.py
-examples/xcorr_demo.py
-examples/zoom_window.py
-examples/zorder_demo.py
-examples/data/AAPL.dat
-examples/data/INTC.dat
-examples/data/ct.raw
-examples/data/eeg.dat
-examples/data/embedding_in_wx3.xrc
-examples/data/intc.csv
-examples/data/lena.jpg
-examples/data/membrane.dat
-examples/data/msft.csv
-examples/data/s1045.ima
-examples/units/__init__.py
-examples/units/artist_tests.py
-examples/units/bar_unit_demo.py
-examples/units/basic_units.py
-examples/units/date_converter.py
-examples/units/date_support.py
-examples/units/evans_test.py
-examples/units/evans_test2.py
-examples/units/radian_demo.py
-examples/units/units_sample.py
-examples/units/units_scatter.py
-examples/widgets/README
-examples/widgets/buttons.py
-examples/widgets/check_buttons.py
-examples/widgets/cursor.py
-examples/widgets/multicursor.py
-examples/widgets/radio_buttons.py
-examples/widgets/rectangle_selector.py
-examples/widgets/sliders.py
-examples/widgets/span_selector.py
-lib/pylab.py
-lib/dateutil/__init__.py
-lib/dateutil/easter.py
-lib/dateutil/parser.py
-lib/dateutil/relativedelta.py
-lib/dateutil/rrule.py
-lib/dateutil/tz.py
-lib/matplotlib/.cvsignore
-lib/matplotlib/__init__.py
-lib/matplotlib/_cm.py
-lib/matplotlib/_contour.py
-lib/matplotlib/_image.py
-lib/matplotlib/_mathtext_data.py
-lib/matplotlib/_pylab_helpers.py
-lib/matplotlib/_transforms.py
-lib/matplotlib/afm.py
-lib/matplotlib/agg.py
-lib/matplotlib/art3d.py
-lib/matplotlib/artist.py
-lib/matplotlib/artist.py~
-lib/matplotlib/axes.py
-lib/matplotlib/axes.py~
-lib/matplotlib/axes3d.py
-lib/matplotlib/axis.py
-lib/matplotlib/axis3d.py
-lib/matplotlib/backend_bases.py
-lib/matplotlib/cbook.py
-lib/matplotlib/cm.py
-lib/matplotlib/collections.py
-lib/matplotlib/colorbar.py
-lib/matplotlib/colors.py
-lib/matplotlib/contour.py
-lib/matplotlib/dates.py
-lib/matplotlib/dviread.py
-lib/matplotlib/figure.py
-lib/matplotlib/finance.py
-lib/matplotlib/font_manager.py
-lib/matplotlib/image.py
-lib/matplotlib/legend.py
-lib/matplotlib/lines.py
-lib/matplotlib/mathtext.py
-lib/matplotlib/mathtext2.py
-lib/matplotlib/mlab.py
-lib/matplotlib/nxutils.py
-lib/matplotlib/patches.py
-lib/matplotlib/proj3d.py
-lib/matplotlib/pylab.py
-lib/matplotlib/pyparsing.py
-lib/matplotlib/quiver.py
-lib/matplotlib/table.py
-lib/matplotlib/texmanager.py
-lib/matplotlib/text.py
-lib/matplotlib/ticker.py
-lib/matplotlib/transforms.py
-lib/matplotlib/units.py
-lib/matplotlib/widgets.py
-lib/matplotlib/windowing.py
-lib/matplotlib/backends/.cvsignore
-lib/matplotlib/backends/__init__.py
-lib/matplotlib/backends/backend_agg.py
-lib/matplotlib/backends/backend_agg2.py
-lib/matplotlib/backends/backend_cairo.py
-lib/matplotlib/backends/backend_cocoaagg.py
-lib/matplotlib/backends/backend_emf.py
-lib/matplotlib/backends/backend_fltkagg.py
-lib/matplotlib/backends/backend_gd.py
-lib/matplotlib/backends/backend_gdk.py
-lib/matplotlib/backends/backend_gtk.py
-lib/matplotlib/backends/backend_gtkagg.py
-lib/matplotlib/backends/backend_gtkcairo.py
-lib/matplotlib/backends/backend_paint.py
-lib/matplotlib/backends/backend_pdf.py
-lib/matplotlib/backends/backend_ps.py
-lib/matplotlib/backends/backend_qt.py
-lib/matplotlib/backends/backend_qt4.py
-lib/matplotlib/backends/backend_qt4agg.py
-lib/matplotlib/backends/backend_qtagg.py
-lib/matplotlib/backends/backend_svg.py
-lib/matplotlib/backends/backend_template.py
-lib/matplotlib/backends/backend_tkagg.py
-lib/matplotlib/backends/backend_wx.py
-lib/matplotlib/backends/backend_wxagg.py
-lib/matplotlib/backends/tkagg.py
-lib/matplotlib/backends/Matplotlib.nib/classes.nib
-lib/matplotlib/backends/Matplotlib.nib/info.nib
-lib/matplotlib/backends/Matplotlib.nib/keyedobjects.nib
-lib/matplotlib/enthought/__init__.py
-lib/matplotlib/enthought/resource/__init__.py
-lib/matplotlib/enthought/resource/resource_factory.py
-lib/matplotlib/enthought/resource/resource_manager.py
-lib/matplotlib/enthought/resource/resource_path.py
-lib/matplotlib/enthought/resource/resource_reference.py
-lib/matplotlib/enthought/traits/__init__.py
-lib/matplotlib/enthought/traits/category.py
-lib/matplotlib/enthought/traits/ctraits.c
-lib/matplotlib/enthought/traits/has_traits.py
-lib/matplotlib/enthought/traits/info_traits.py
-lib/matplotlib/enthought/traits/standard.py
-lib/matplotlib/enthought/traits/trait_base.py
-lib/matplotlib/enthought/traits/trait_db.py
-lib/matplotlib/enthought/traits/trait_errors.py
-lib/matplotlib/enthought/traits/trait_handlers.py
-lib/matplotlib/enthought/traits/trait_notifiers.py
-lib/matplotlib/enthought/traits/trait_numeric.py
-lib/matplotlib/enthought/traits/traits.py
-lib/matplotlib/enthought/traits/ui/__init__.py
-lib/matplotlib/enthought/traits/ui/editor.py
-lib/matplotlib/enthought/traits/ui/editor_factory.py
-lib/matplotlib/enthought/traits/ui/editors.py
-lib/matplotlib/enthought/traits/ui/group.py
-lib/matplotlib/enthought/traits/ui/handler.py
-lib/matplotlib/enthought/traits/ui/help.py
-lib/matplotlib/enthought/traits/ui/help_template.py
-lib/matplotlib/enthought/traits/ui/helper.py
-lib/matplotlib/enthought/traits/ui/include.py
-lib/matplotlib/enthought/traits/ui/item.py
-lib/matplotlib/enthought/traits/ui/menu.py
-lib/matplotlib/enthought/traits/ui/toolkit.py
-lib/matplotlib/enthought/traits/ui/tree_node.py
-lib/matplotlib/enthought/traits/ui/ui.py
-lib/matplotlib/enthought/traits/ui/ui_info.py
-lib/matplotlib/enthought/traits/ui/ui_traits.py
-lib/matplotlib/enthought/traits/ui/undo.py
-lib/matplotlib/enthought/traits/ui/view.py
-lib/matplotlib/enthought/traits/ui/view_element.py
-lib/matplotlib/enthought/traits/ui/view_elements.py
-lib/matplotlib/enthought/traits/ui/null/__init__.py
-lib/matplotlib/enthought/traits/ui/null/color_trait.py
-lib/matplotlib/enthought/traits/ui/null/font_trait.py
-lib/matplotlib/enthought/traits/ui/null/rgb_color_trait.py
-lib/matplotlib/enthought/traits/ui/null/rgba_color_trait.py
-lib/matplotlib/enthought/traits/ui/null/toolkit.py
-lib/matplotlib/enthought/util/__init__.py
-lib/matplotlib/enthought/util/resource.py
-lib/matplotlib/mpl-data/matplotlibrc
-lib/matplotlib/mpl-data/fonts/afm/cmex10.afm
-lib/matplotlib/mpl-data/fonts/afm/cmmi10.afm
-lib/matplotlib/mpl-data/fonts/afm/cmr10.afm
-lib/matplotlib/mpl-data/fonts/afm/cmsy10.afm
-lib/matplotlib/mpl-data/fonts/afm/cmtt10.afm
-lib/matplotlib/mpl-data/fonts/afm/pagd8a.afm
-lib/matplotlib/mpl-data/fonts/afm/pagdo8a.afm
-lib/matplotlib/mpl-data/fonts/afm/pagk8a.afm
-lib/matplotlib/mpl-data/fonts/afm/pagko8a.afm
-lib/matplotlib/mpl-data/fonts/afm/pbkd8a.afm
-lib/matplotlib/mpl-data/fonts/afm/pbkdi8a.afm
-lib/matplotlib/mpl-data/fonts/afm/pbkl8a.afm
-lib/matplotlib/mpl-data/fonts/afm/pbkli8a.afm
-lib/matplotlib/mpl-data/fonts/afm/pcrb8a.afm
-lib/matplotlib/mpl-data/fonts/afm/pcrbo8a.afm
-lib/matplotlib/mpl-data/fonts/afm/pcrr8a.afm
-lib/matplotlib/mpl-data/fonts/afm/pcrro8a.afm
-lib/matplotlib/mpl-data/fonts/afm/phvb8a.afm
-lib/matplotlib/mpl-data/fonts/afm/phvb8an.afm
-lib/matplotlib/mpl-data/fonts/afm/phvbo8a.afm
-lib/matplotlib/mpl-data/fonts/afm/phvbo8an.afm
-lib/matplotlib/mpl-data/fonts/afm/phvl8a.afm
-lib/matplotlib/mpl-data/fonts/afm/phvlo8a.afm
-lib/matplotlib/mpl-data/fonts/afm/phvr8a.afm
-lib/matplotlib/mpl-data/fonts/afm/phvr8an.afm
-lib/matplotlib/mpl-data/fonts/afm/phvro8a.afm
-lib/matplotlib/mpl-data/fonts/afm/phvro8an.afm
-lib/matplotlib/mpl-data/fonts/afm/pncb8a.afm
-lib/matplotlib/mpl-data/fonts/afm/pncbi8a.afm
-lib/matplotlib/mpl-data/fonts/afm/pncr8a.afm
-lib/matplotlib/mpl-data/fonts/afm/pncri8a.afm
-lib/matplotlib/mpl-data/fonts/afm/pplb8a.afm
-lib/matplotlib/mpl-data/fonts/afm/pplbi8a.afm
-lib/matplotlib/mpl-data/fonts/afm/pplr8a.afm
-lib/matplotlib/mpl-data/fonts/afm/pplri8a.afm
-lib/matplotlib/mpl-data/fonts/afm/psyr.afm
-lib/matplotlib/mpl-data/fonts/afm/ptmb8a.afm
-lib/matplotlib/mpl-data/fonts/afm/ptmbi8a.afm
-lib/matplotlib/mpl-data/fonts/afm/ptmr8a.afm
-lib/matplotlib/mpl-data/fonts/afm/ptmri8a.afm
-lib/matplotlib/mpl-data/fonts/afm/putb8a.afm
-lib/matplotlib/mpl-data/fonts/afm/putbi8a.afm
-lib/matplotlib/mpl-data/fonts/afm/putr8a.afm
-lib/matplotlib/mpl-data/fonts/afm/putri8a.afm
-lib/matplotlib/mpl-data/fonts/afm/pzcmi8a.afm
-lib/matplotlib/mpl-data/fonts/afm/pzdr.afm
-lib/matplotlib/mpl-data/fonts/pdfcorefonts/Courier-Bold.afm
-lib/matplotlib/mpl-data/fonts/pdfcorefonts/Courier-BoldOblique.afm
-lib/matplotlib/mpl-data/fonts/pdfcorefonts/Courier-Oblique.afm
-lib/matplotlib/mpl-data/fonts/pdfcorefonts/Courier.afm
-lib/matplotlib/mpl-data/fonts/pdfcorefonts/Helvetica-Bold.afm
-lib/matplotlib/mpl-data/fonts/pdfcorefonts/Helvetica-BoldOblique.afm
-lib/matplotlib/mpl-data/fonts/pdfcorefonts/Helvetica-Oblique.afm
-lib/matplotlib/mpl-data/fonts/pdfcorefonts/Helvetica.afm
-lib/matplotlib/mpl-data/fonts/pdfcorefonts/Symbol.afm
-lib/matplotlib/mpl-data/fonts/pdfcorefonts/Times-Bold.afm
-lib/matplotlib/mpl-data/fonts/pdfcorefonts/Times-BoldItalic.afm
-lib/matplotlib/mpl-data/fonts/pdfcorefonts/Times-Italic.afm
-lib/matplotlib/mpl-data/fonts/pdfcorefonts/Times-Roman.afm
-lib/matplotlib/mpl-data/fonts/pdfcorefonts/ZapfDingbats.afm
-lib/matplotlib/mpl-data/fonts/pdfcorefonts/readme.txt
-lib/matplotlib/mpl-data/fonts/ttf/COPYRIGHT.TXT
-lib/matplotlib/mpl-data/fonts/ttf/README.TXT
-lib/matplotlib/mpl-data/fonts/ttf/RELEASENOTES.TXT
-lib/matplotlib/mpl-data/fonts/ttf/Vera.ttf
-lib/matplotlib/mpl-data/fonts/ttf/VeraBI.ttf
-lib/matplotlib/mpl-data/fonts/ttf/VeraBd.ttf
-lib/matplotlib/mpl-data/fonts/ttf/VeraIt.ttf
-lib/matplotlib/mpl-data/fonts/ttf/VeraMoBI.ttf
-lib/matplotlib/mpl-data/fonts/ttf/VeraMoBd.ttf
-lib/matplotlib/mpl-data/fonts/ttf/VeraMoIt.ttf
-lib/matplotlib/mpl-data/fonts/ttf/VeraMono.ttf
-lib/matplotlib/mpl-data/fonts/ttf/VeraSe.ttf
-lib/matplotlib/mpl-data/fonts/ttf/VeraSeBd.ttf
-lib/matplotlib/mpl-data/fonts/ttf/cmex10.ttf
-lib/matplotlib/mpl-data/fonts/ttf/cmmi10.ttf
-lib/matplotlib/mpl-data/fonts/ttf/cmr10.ttf
-lib/matplotlib/mpl-data/fonts/ttf/cmsy10.ttf
-lib/matplotlib/mpl-data/fonts/ttf/cmtt10.ttf
-lib/matplotlib/mpl-data/fonts/ttf/local.conf
-lib/matplotlib/mpl-data/images/back.png
-lib/matplotlib/mpl-data/images/back.ppm
-lib/matplotlib/mpl-data/images/back.svg
-lib/matplotlib/mpl-data/images/back.xpm
-lib/matplotlib/mpl-data/images/filesave.png
-lib/matplotlib/mpl-data/images/filesave.ppm
-lib/matplotlib/mpl-data/images/filesave.svg
-lib/matplotlib/mpl-data/images/filesave.xpm
-lib/matplotlib/mpl-data/images/forward.png
-lib/matplotlib/mpl-data/images/forward.ppm
-lib/matplotlib/mpl-data/images/forward.svg
-lib/matplotlib/mpl-data/images/forward.xpm
-lib/matplotlib/mpl-data/images/hand.png
-lib/matplotlib/mpl-data/images/hand.ppm
-lib/matplotlib/mpl-data/images/hand.svg
-lib/matplotlib/mpl-data/images/hand.xpm
-lib/matplotlib/mpl-data/images/home.png
-lib/matplotlib/mpl-data/images/home.ppm
-lib/matplotlib/mpl-data/images/home.svg
-lib/matplotlib/mpl-data/images/home.xpm
-lib/matplotlib/mpl-data/images/matplotlib.png
-lib/matplotlib/mpl-data/images/matplotlib.svg
-lib/matplotlib/mpl-data/images/move.png
-lib/matplotlib/mpl-data/images/move.ppm
-lib/matplotlib/mpl-data/images/move.svg
-lib/matplotlib/mpl-data/images/move.xpm
-lib/matplotlib/mpl-data/images/stock_close.ppm
-lib/matplotlib/mpl-data/images/stock_close.xpm
-lib/matplotlib/mpl-data/images/stock_down.ppm
-lib/matplotlib/mpl-data/images/stock_down.xpm
-lib/matplotlib/mpl-data/images/stock_left.ppm
-lib/matplotlib/mpl-data/images/stock_left.xpm
-lib/matplotlib/mpl-data/images/stock_refresh.ppm
-lib/matplotlib/mpl-data/images/stock_refresh.xpm
-lib/matplotlib/mpl-data/images/stock_right.ppm
-lib/matplotlib/mpl-data/images/stock_right.xpm
-lib/matplotlib/mpl-data/images/stock_save_as.ppm
-lib/matplotlib/mpl-data/images/stock_save_as.xpm
-lib/matplotlib/mpl-data/images/stock_up.ppm
-lib/matplotlib/mpl-data/images/stock_up.xpm
-lib/matplotlib/mpl-data/images/stock_zoom-in.ppm
-lib/matplotlib/mpl-data/images/stock_zoom-in.xpm
-lib/matplotlib/mpl-data/images/stock_zoom-out.ppm
-lib/matplotlib/mpl-data/images/stock_zoom-out.xpm
-lib/matplotlib/mpl-data/images/subplots.png
-lib/matplotlib/mpl-data/images/subplots.ppm
-lib/matplotlib/mpl-data/images/subplots.xpm
-lib/matplotlib/mpl-data/images/zoom_to_rect.png
-lib/matplotlib/mpl-data/images/zoom_to_rect.ppm
-lib/matplotlib/mpl-data/images/zoom_to_rect.svg
-lib/matplotlib/mpl-data/images/zoom_to_rect.xpm
-lib/matplotlib/numerix/.cvsignore
-lib/matplotlib/numerix/__init__.py
-lib/matplotlib/numerix/_na_imports.py
-lib/matplotlib/numerix/_nc_imports.py
-lib/matplotlib/numerix/_sp_imports.py
-lib/matplotlib/numerix/fft/__init__.py
-lib/matplotlib/numerix/linear_algebra/__init__.py
-lib/matplotlib/numerix/ma/__init__.py
-lib/matplotlib/numerix/mlab/.cvsignore
-lib/matplotlib/numerix/mlab/__init__.py
-lib/matplotlib/numerix/random_array/__init__.py
-lib/matplotlib/toolkits/__init__.py
-lib/pytz/__init__.py
-lib/pytz/reference.py
-lib/pytz/test_tzinfo.py
-lib/pytz/tzinfo.py
-lib/pytz/zoneinfo/CET.py
-lib/pytz/zoneinfo/CST6CDT.py
-lib/pytz/zoneinfo/Cuba.py
-lib/pytz/zoneinfo/EET.py
-lib/pytz/zoneinfo/EST.py
-lib/pytz/zoneinfo/EST5EDT.py
-lib/pytz/zoneinfo/Egypt.py
-lib/pytz/zoneinfo/Eire.py
-lib/pytz/zoneinfo/GB.py
-lib/pytz/zoneinfo/GB_minus_Eire.py
-lib/pytz/zoneinfo/GMT.py
-lib/pytz/zoneinfo/GMT0.py
-lib/pytz/zoneinfo/GMT_minus_0.py
-lib/pytz/zoneinfo/GMT_plus_0.py
-lib/pytz/zoneinfo/Greenwich.py
-lib/pytz/zoneinfo/HST.py
-lib/pytz/zoneinfo/Hongkong.py
-lib/pytz/zoneinfo/Iceland.py
-lib/pytz/zoneinfo/Iran.py
-lib/pytz/zoneinfo/Israel.py
-lib/pytz/zoneinfo/Jamaica.py
-lib/pytz/zoneinfo/Japan.py
-lib/pytz/zoneinfo/Kwajalein.py
-lib/pytz/zoneinfo/Libya.py
-lib/pytz/zoneinfo/MET.py
-lib/pytz/zoneinfo/MST.py
-lib/pytz/zoneinfo/MST7MDT.py
-lib/pytz/zoneinfo/NZ.py
-lib/pytz/zoneinfo/NZ_minus_CHAT.py
-lib/pytz/zoneinfo/Navajo.py
-lib/pytz/zoneinfo/PRC.py
-lib/pytz/zoneinfo/PST8PDT.py
-lib/pytz/zoneinfo/Poland.py
-lib/pytz/zoneinfo/Portugal.py
-lib/pytz/zoneinfo/ROC.py
-lib/pytz/zoneinfo/ROK.py
-lib/pytz/zoneinfo/Singapore.py
-lib/pytz/zoneinfo/Turkey.py
-lib/pytz/zoneinfo/UCT.py
-lib/pytz/zoneinfo/UTC.py
-lib/pytz/zoneinfo/Universal.py
-lib/pytz/zoneinfo/WET.py
-lib/pytz/zoneinfo/W_minus_SU.py
-lib/pytz/zoneinfo/Zulu.py
-lib/pytz/zoneinfo/__init__.py
-lib/pytz/zoneinfo/posixrules.py
-lib/pytz/zoneinfo/Africa/Abidjan.py
-lib/pytz/zoneinfo/Africa/Accra.py
-lib/pytz/zoneinfo/Africa/Addis_Ababa.py
-lib/pytz/zoneinfo/Africa/Algiers.py
-lib/pytz/zoneinfo/Africa/Asmera.py
-lib/pytz/zoneinfo/Africa/Bamako.py
-lib/pytz/zoneinfo/Africa/Bangui.py
-lib/pytz/zoneinfo/Africa/Banjul.py
-lib/pytz/zoneinfo/Africa/Bissau.py
-lib/pytz/zoneinfo/Africa/Blantyre.py
-lib/pytz/zoneinfo/Africa/Brazzaville.py
-lib/pytz/zoneinfo/Africa/Bujumbura.py
-lib/pytz/zoneinfo/Africa/Cairo.py
-lib/pytz/zoneinfo/Africa/Casablanca.py
-lib/pytz/zoneinfo/Africa/Ceuta.py
-lib/pytz/zoneinfo/Africa/Conakry.py
-lib/pytz/zoneinfo/Africa/Dakar.py
-lib/pytz/zoneinfo/Africa/Dar_es_Salaam.py
-lib/pytz/zoneinfo/Africa/Djibouti.py
-lib/pytz/zoneinfo/Africa/Douala.py
-lib/pytz/zoneinfo/Africa/El_Aaiun.py
-lib/pytz/zoneinfo/Africa/Freetown.py
-lib/pytz/zoneinfo/Africa/Gaborone.py
-lib/pytz/zoneinfo/Africa/Harare.py
-lib/pytz/zoneinfo/Africa/Johannesburg.py
-lib/pytz/zoneinfo/Africa/Kampala.py
-lib/pytz/zoneinfo/Africa/Khartoum.py
-lib/pytz/zoneinfo/Africa/Kigali.py
-lib/pytz/zoneinfo/Africa/Kinshasa.py
-lib/pytz/zoneinfo/Africa/Lagos.py
-lib/pytz/zoneinfo/Africa/Libreville.py
-lib/pytz/zoneinfo/Africa/Lome.py
-lib/pytz/zoneinfo/Africa/Luanda.py
-lib/pytz/zoneinfo/Africa/Lubumbashi.py
-lib/pytz/zoneinfo/Africa/Lusaka.py
-lib/pytz/zoneinfo/Africa/Malabo.py
-lib/pytz/zoneinfo/Africa/Maputo.py
-lib/pytz/zoneinfo/Africa/Maseru.py
-lib/pytz/zoneinfo/Africa/Mbabane.py
-lib/pytz/zoneinfo/Africa/Mogadishu.py
-lib/pytz/zoneinfo/Africa/Monrovia.py
-lib/pytz/zoneinfo/Africa/Nairobi.py
-lib/pytz/zoneinfo/Africa/Ndjamena.py
-lib/pytz/zoneinfo/Africa/Niamey.py
-lib/pytz/zoneinfo/Africa/Nouakchott.py
-lib/pytz/zoneinfo/Africa/Ouagadougou.py
-lib/pytz/zoneinfo/Africa/Porto_minus_Novo.py
-lib/pytz/zoneinfo/Africa/Sao_Tome.py
-lib/pytz/zoneinfo/Africa/Timbuktu.py
-lib/pytz/zoneinfo/Africa/Tripoli.py
-lib/pytz/zoneinfo/Africa/Tunis.py
-lib/pytz/zoneinfo/Africa/Windhoek.py
-lib/pytz/zoneinfo/Africa/__init__.py
-lib/pytz/zoneinfo/America/Adak.py
-lib/pytz/zoneinfo/America/Anchorage.py
-lib/pytz/zoneinfo/America/Anguilla.py
-lib/pytz/zoneinfo/America/Antigua.py
-lib/pytz/zoneinfo/America/Araguaina.py
-lib/pytz/zoneinfo/America/Aruba.py
-lib/pytz/zoneinfo/America/Asuncion.py
-lib/pytz/zoneinfo/America/Atka.py
-lib/pytz/zoneinfo/America/Bahia.py
-lib/pytz/zoneinfo/America/Barbados.py
-lib/pytz/zoneinfo/America/Belem.py
-lib/pytz/zoneinfo/America/Belize.py
-lib/pytz/zoneinfo/America/Boa_Vista.py
-lib/pytz/zoneinfo/America/Bogota.py
-lib/pytz/zoneinfo/America/Boise.py
-lib/pytz/zoneinfo/America/Buenos_Aires.py
-lib/pytz/zoneinfo/America/Cambridge_Bay.py
-lib/pytz/zoneinfo/America/Campo_Grande.py
-lib/pytz/zoneinfo/America/Cancun.py
-lib/pytz/zoneinfo/America/Caracas.py
-lib/pytz/zoneinfo/America/Catamarca.py
-lib/pytz/zoneinfo/America/Cayenne.py
-lib/pytz/zoneinfo/America/Cayman.py
-lib/pytz/zoneinfo/America/Chicago.py
-lib/pytz/zoneinfo/America/Chihuahua.py
-lib/pytz/zoneinfo/America/Cordoba.py
-lib/pytz/zoneinfo/America/Costa_Rica.py
-lib/pytz/zoneinfo/America/Cuiaba.py
-lib/pytz/zoneinfo/America/Curacao.py
-lib/pytz/zoneinfo/America/Danmarkshavn.py
-lib/pytz/zoneinfo/America/Dawson.py
-lib/pytz/zoneinfo/America/Dawson_Creek.py
-lib/pytz/zoneinfo/America/Denver.py
-lib/pytz/zoneinfo/America/Detroit.py
-lib/pytz/zoneinfo/America/Dominica.py
-lib/pytz/zoneinfo/America/Edmonton.py
-lib/pytz/zoneinfo/America/Eirunepe.py
-lib/pytz/zoneinfo/America/El_Salvador.py
-lib/pytz/zoneinfo/America/Ensenada.py
-lib/pytz/zoneinfo/America/Fort_Wayne.py
-lib/pytz/zoneinfo/America/Fortaleza.py
-lib/pytz/zoneinfo/America/Glace_Bay.py
-lib/pytz/zoneinfo/America/Godthab.py
-lib/pytz/zoneinfo/America/Goose_Bay.py
-lib/pytz/zoneinfo/America/Grand_Turk.py
-lib/pytz/zoneinfo/America/Grenada.py
-lib/pytz/zoneinfo/America/Guadeloupe.py
-lib/pytz/zoneinfo/America/Guatemala.py
-lib/pytz/zoneinfo/America/Guayaquil.py
-lib/pytz/zoneinfo/America/Guyana.py
-lib/pytz/zoneinfo/America/Halifax.py
-lib/pytz/zoneinfo/America/Havana.py
-lib/pytz/zoneinfo/America/Hermosillo.py
-lib/pytz/zoneinfo/America/Indianapolis.py
-lib/pytz/zoneinfo/America/Inuvik.py
-lib/pytz/zoneinfo/America/Iqaluit.py
-lib/pytz/zoneinfo/America/Jamaica.py
-lib/pytz/zoneinfo/America/Jujuy.py
-lib/pytz/zoneinfo/America/Juneau.py
-lib/pytz/zoneinfo/America/Knox_IN.py
-lib/pytz/zoneinfo/America/La_Paz.py
-lib/pytz/zoneinfo/America/Lima.py
-lib/pytz/zoneinfo/America/Los_Angeles.py
-lib/pytz/zoneinfo/America/Louisville.py
-lib/pytz/zoneinfo/America/Maceio.py
-lib/pytz/zoneinfo/America/Managua.py
-lib/pytz/zoneinfo/America/Manaus.py
-lib/pytz/zoneinfo/America/Martinique.py
-lib/pytz/zoneinfo/America/Mazatlan.py
-lib/pytz/zoneinfo/America/Mendoza.py
-lib/pytz/zoneinfo/America/Menominee.py
-lib/pytz/zoneinfo/America/Merida.py
-lib/pytz/zoneinfo/America/Mexico_City.py
-lib/pytz/zoneinfo/America/Miquelon.py
-lib/pytz/zoneinfo/America/Monterrey.py
-lib/pytz/zoneinfo/America/Montevideo.py
-lib/pytz/zoneinfo/America/Montreal.py
-lib/pytz/zoneinfo/America/Montserrat.py
-lib/pytz/zoneinfo/America/Nassau.py
-lib/pytz/zoneinfo/America/New_York.py
-lib/pytz/zoneinfo/America/Nipigon.py
-lib/pytz/zoneinfo/America/Nome.py
-lib/pytz/zoneinfo/America/Noronha.py
-lib/pytz/zoneinfo/America/Panama.py
-lib/pytz/zoneinfo/America/Pangnirtung.py
-lib/pytz/zoneinfo/America/Paramaribo.py
-lib/pytz/zoneinfo/America/Phoenix.py
-lib/pytz/zoneinfo/America/Port_minus_au_minus_Prince.py
-lib/pytz/zoneinfo/America/Port_of_Spain.py
-lib/pytz/zoneinfo/America/Porto_Acre.py
-lib/pytz/zoneinfo/America/Porto_Velho.py
-lib/pytz/zoneinfo/America/Puerto_Rico.py
-lib/pytz/zoneinfo/America/Rainy_River.py
-lib/pytz/zoneinfo/America/Rankin_Inlet.py
-lib/pytz/zoneinfo/America/Recife.py
-lib/pytz/zoneinfo/America/Regina.py
-lib/pytz/zoneinfo/America/Rio_Branco.py
-lib/pytz/zoneinfo/America/Rosario.py
-lib/pytz/zoneinfo/America/Santiago.py
-lib/pytz/zoneinfo/America/Santo_Domingo.py
-lib/pytz/zoneinfo/America/Sao_Paulo.py
-lib/pytz/zoneinfo/America/Scoresbysund.py
-lib/pytz/zoneinfo/America/Shiprock.py
-lib/pytz/zoneinfo/America/St_Johns.py
-lib/pytz/zoneinfo/America/St_Kitts.py
-lib/pytz/zoneinfo/America/St_Lucia.py
-lib/pytz/zoneinfo/America/St_Thomas.py
-lib/pytz/zoneinfo/America/St_Vincent.py
-lib/pytz/zoneinfo/America/Swift_Current.py
-lib/pytz/zoneinfo/America/Tegucigalpa.py
-lib/pytz/zoneinfo/America/Thule.py
-lib/pytz/zoneinfo/America/Thunder_Bay.py
-lib/pytz/zoneinfo/America/Tijuana.py
-lib/pytz/zoneinfo/America/Toronto.py
-lib/pytz/zoneinfo/America/Tortola.py
-lib/pytz/zoneinfo/America/Vancouver.py
-lib/pytz/zoneinfo/America/Virgin.py
-lib/pytz/zoneinfo/America/Whitehorse.py
-lib/pytz/zoneinfo/America/Winnipeg.py
-lib/pytz/zoneinfo/America/Yakutat.py
-lib/pytz/zoneinfo/America/Yellowknife.py
-lib/pytz/zoneinfo/America/__init__.py
-lib/pytz/zoneinfo/America/Argentina/Buenos_Aires.py
-lib/pytz/zoneinfo/America/Argentina/Catamarca.py
-lib/pytz/zoneinfo/America/Argentina/ComodRivadavia.py
-lib/pytz/zoneinfo/America/Argentina/Cordoba.py
-lib/pytz/zoneinfo/America/Argentina/Jujuy.py
-lib/pytz/zoneinfo/America/Argentina/La_Rioja.py
-lib/pytz/zoneinfo/America/Argentina/Mendoza.py
-lib/pytz/zoneinfo/America/Argentina/Rio_Gallegos.py
-lib/pytz/zoneinfo/America/Argentina/San_Juan.py
-lib/pytz/zoneinfo/America/Argentina/Tucuman.py
-lib/pytz/zoneinfo/America/Argentina/Ushuaia.py
-lib/pytz/zoneinfo/America/Argentina/__init__.py
-lib/pytz/zoneinfo/America/Indiana/Indianapolis.py
-lib/pytz/zoneinfo/America/Indiana/Knox.py
-lib/pytz/zoneinfo/America/Indiana/Marengo.py
-lib/pytz/zoneinfo/America/Indiana/Vevay.py
-lib/pytz/zoneinfo/America/Indiana/__init__.py
-lib/pytz/zoneinfo/America/Kentucky/Louisville.py
-lib/pytz/zoneinfo/America/Kentucky/Monticello.py
-lib/pytz/zoneinfo/America/Kentucky/__init__.py
-lib/pytz/zoneinfo/America/North_Dakota/Center.py
-lib/pytz/zoneinfo/America/North_Dakota/__init__.py
-lib/pytz/zoneinfo/Antarctica/Casey.py
-lib/pytz/zoneinfo/Antarctica/Davis.py
-lib/pytz/zoneinfo/Antarctica/DumontDUrville.py
-lib/pytz/zoneinfo/Antarctica/Mawson.py
-lib/pytz/zoneinfo/Antarctica/McMurdo.py
-lib/pytz/zoneinfo/Antarctica/Palmer.py
-lib/pytz/zoneinfo/Antarctica/Rothera.py
-lib/pytz/zoneinfo/Antarctica/South_Pole.py
-lib/pytz/zoneinfo/Antarctica/Syowa.py
-lib/pytz/zoneinfo/Antarctica/Vostok.py
-lib/pytz/zoneinfo/Antarctica/__init__.py
-lib/pytz/zoneinfo/Arctic/Longyearbyen.py
-lib/pytz/zoneinfo/Arctic/__init__.py
-lib/pytz/zoneinfo/Asia/Aden.py
-lib/pytz/zoneinfo/Asia/Almaty.py
-lib/pytz/zoneinfo/Asia/Amman.py
-lib/pytz/zoneinfo/Asia/Anadyr.py
-lib/pytz/zoneinfo/Asia/Aqtau.py
-lib/pytz/zoneinfo/Asia/Aqtobe.py
-lib/pytz/zoneinfo/Asia/Ashgabat.py
-lib/pytz/zoneinfo/Asia/Ashkhabad.py
-lib/pytz/zoneinfo/Asia/Baghdad.py
-lib/pytz/zoneinfo/Asia/Bahrain.py
-lib/pytz/zoneinfo/Asia/Baku.py
-lib/pytz/zoneinfo/Asia/Bangkok.py
-lib/pytz/zoneinfo/Asia/Beirut.py
-lib/pytz/zoneinfo/Asia/Bishkek.py
-lib/pytz/zoneinfo/Asia/Brunei.py
-lib/pytz/zoneinfo/Asia/Calcutta.py
-lib/pytz/zoneinfo/Asia/Choibalsan.py
-lib/pytz/zoneinfo/Asia/Chongqing.py
-lib/pytz/zoneinfo/Asia/Chungking.py
-lib/pytz/zoneinfo/Asia/Colombo.py
-lib/pytz/zoneinfo/Asia/Dacca.py
-lib/pytz/zoneinfo/Asia/Damascus.py
-lib/pytz/zoneinfo/Asia/Dhaka.py
-lib/pytz/zoneinfo/Asia/Dili.py
-lib/pytz/zoneinfo/Asia/Dubai.py
-lib/pytz/zoneinfo/Asia/Dushanbe.py
-lib/pytz/zoneinfo/Asia/Gaza.py
-lib/pytz/zoneinfo/Asia/Harbin.py
-lib/pytz/zoneinfo/Asia/Hong_Kong.py
-lib/pytz/zoneinfo/Asia/Hovd.py
-lib/pytz/zoneinfo/Asia/Irkutsk.py
-lib/pytz/zoneinfo/Asia/Istanbul.py
-lib/pytz/zoneinfo/Asia/Jakarta.py
-lib/pytz/zoneinfo/Asia/Jayapura.py
-lib/pytz/zoneinfo/Asia/Jerusalem.py
-lib/pytz/zoneinfo/Asia/Kabul.py
-lib/pytz/zoneinfo/Asia/Kamchatka.py
-lib/pytz/zoneinfo/Asia/Karachi.py
-lib/pytz/zoneinfo/Asia/Kashgar.py
-lib/pytz/zoneinfo/Asia/Katmandu.py
-lib/pytz/zoneinfo/Asia/Krasnoyarsk.py
-lib/pytz/zoneinfo/Asia/Kuala_Lumpur.py
-lib/pytz/zoneinfo/Asia/Kuching.py
-lib/pytz/zoneinfo/Asia/Kuwait.py
-lib/pytz/zoneinfo/Asia/Macao.py
-lib/pytz/zoneinfo/Asia/Macau.py
-lib/pytz/zoneinfo/Asia/Magadan.py
-lib/pytz/zoneinfo/Asia/Makassar.py
-lib/pytz/zoneinfo/Asia/Manila.py
-lib/pytz/zoneinfo/Asia/Muscat.py
-lib/pytz/zoneinfo/Asia/Nicosia.py
-lib/pytz/zoneinfo/Asia/Novosibirsk.py
-lib/pytz/zoneinfo/Asia/Omsk.py
-lib/pytz/zoneinfo/Asia/Oral.py
-lib/pytz/zoneinfo/Asia/Phnom_Penh.py
-lib/pytz/zoneinfo/Asia/Pontianak.py
-lib/pytz/zoneinfo/Asia/Pyongyang.py
-lib/pytz/zoneinfo/Asia/Qatar.py
-lib/pytz/zoneinfo/Asia/Qyzylorda.py
-lib/pytz/zoneinfo/Asia/Rangoon.py
-lib/pytz/zoneinfo/Asia/Riyadh.py
-lib/pytz/zoneinfo/Asia/Saigon.py
-lib/pytz/zoneinfo/Asia/Sakhalin.py
-lib/pytz/zoneinfo/Asia/Samarkand.py
-lib/pytz/zoneinfo/Asia/Seoul.py
-lib/pytz/zoneinfo/Asia/Shanghai.py
-lib/pytz/zoneinfo/Asia/Singapore.py
-lib/pytz/zoneinfo/Asia/Taipei.py
-lib/pytz/zoneinfo/Asia/Tashkent.py
-lib/pytz/zoneinfo/Asia/Tbilisi.py
-lib/pytz/zoneinfo/Asia/Tehran.py
-lib/pytz/zoneinfo/Asia/Tel_Aviv.py
-lib/pytz/zoneinfo/Asia/Thimbu.py
-lib/pytz/zoneinfo/Asia/Thimphu.py
-lib/pytz/zoneinfo/Asia/Tokyo.py
-lib/pytz/zoneinfo/Asia/Ujung_Pandang.py
-lib/pytz/zoneinfo/Asia/Ulaanbaatar.py
-lib/pytz/zoneinfo/Asia/Ulan_Bator.py
-lib/pytz/zoneinfo/Asia/Urumqi.py
-lib/pytz/zoneinfo/Asia/Vientiane.py
-lib/pytz/zoneinfo/Asia/Vladivostok.py
-lib/pytz/zoneinfo/Asia/Yakutsk.py
-lib/pytz/zoneinfo/Asia/Yekaterinburg.py
-lib/pytz/zoneinfo/Asia/Yerevan.py
-lib/pytz/zoneinfo/Asia/__init__.py
-lib/pytz/zoneinfo/Atlantic/Azores.py
-lib/pytz/zoneinfo/Atlantic/Bermuda.py
-lib/pytz/zoneinfo/Atlantic/Canary.py
-lib/pytz/zoneinfo/Atlantic/Cape_Verde.py
-lib/pytz/zoneinfo/Atlantic/Faeroe.py
-lib/pytz/zoneinfo/Atlantic/Jan_Mayen.py
-lib/pytz/zoneinfo/Atlantic/Madeira.py
-lib/pytz/zoneinfo/Atlantic/Reykjavik.py
-lib/pytz/zoneinfo/Atlantic/South_Georgia.py
-lib/pytz/zoneinfo/Atlantic/St_Helena.py
-lib/pytz/zoneinfo/Atlantic/Stanley.py
-lib/pytz/zoneinfo/Atlantic/__init__.py
-lib/pytz/zoneinfo/Australia/ACT.py
-lib/pytz/zoneinfo/Australia/Adelaide.py
-lib/pytz/zoneinfo/Australia/Brisbane.py
-lib/pytz/zoneinfo/Australia/Broken_Hill.py
-lib/pytz/zoneinfo/Australia/Canberra.py
-lib/pytz/zoneinfo/Australia/Darwin.py
-lib/pytz/zoneinfo/Australia/Hobart.py
-lib/pytz/zoneinfo/Australia/LHI.py
-lib/pytz/zoneinfo/Australia/Lindeman.py
-lib/pytz/zoneinfo/Australia/Lord_Howe.py
-lib/pytz/zoneinfo/Australia/Melbourne.py
-lib/pytz/zoneinfo/Australia/NSW.py
-lib/pytz/zoneinfo/Australia/North.py
-lib/pytz/zoneinfo/Australia/Perth.py
-lib/pytz/zoneinfo/Australia/Queensland.py
-lib/pytz/zoneinfo/Australia/South.py
-lib/pytz/zoneinfo/Australia/Sydney.py
-lib/pytz/zoneinfo/Australia/Tasmania.py
-lib/pytz/zoneinfo/Australia/Victoria.py
-lib/pytz/zoneinfo/Australia/West.py
-lib/pytz/zoneinfo/Australia/Yancowinna.py
-lib/pytz/zoneinfo/Australia/__init__.py
-lib/pytz/zoneinfo/Brazil/Acre.py
-lib/pytz/zoneinfo/Brazil/DeNoronha.py
-lib/pytz/zoneinfo/Brazil/East.py
-lib/pytz/zoneinfo/Brazil/West.py
-lib/pytz/zoneinfo/Brazil/__init__.py
-lib/pytz/zoneinfo/Canada/Atlantic.py
-lib/pytz/zoneinfo/Canada/Central.py
-lib/pytz/zoneinfo/Canada/East_minus_Saskatchewan.py
-lib/pytz/zoneinfo/Canada/Eastern.py
-lib/pytz/zoneinfo/Canada/Mountain.py
-lib/pytz/zoneinfo/Canada/Newfoundland.py
-lib/pytz/zoneinfo/Canada/Pacific.py
-lib/pytz/zoneinfo/Canada/Saskatchewan.py
-lib/pytz/zoneinfo/Canada/Yukon.py
-lib/pytz/zoneinfo/Canada/__init__.py
-lib/pytz/zoneinfo/Chile/Continental.py
-lib/pytz/zoneinfo/Chile/EasterIsland.py
-lib/pytz/zoneinfo/Chile/__init__.py
-lib/pytz/zoneinfo/Etc/GMT.py
-lib/pytz/zoneinfo/Etc/GMT0.py
-lib/pytz/zoneinfo/Etc/GMT_minus_0.py
-lib/pytz/zoneinfo/Etc/GMT_minus_1.py
-lib/pytz/zoneinfo/Etc/GMT_minus_10.py
-lib/pytz/zoneinfo/Etc/GMT_minus_11.py
-lib/pytz/zoneinfo/Etc/GMT_minus_12.py
-lib/pytz/zoneinfo/Etc/GMT_minus_13.py
-lib/pytz/zoneinfo/Etc/GMT_minus_14.py
-lib/pytz/zoneinfo/Etc/GMT_minus_2.py
-lib/pytz/zoneinfo/Etc/GMT_minus_3.py
-lib/pytz/zoneinfo/Etc/GMT_minus_4.py
-lib/pytz/zoneinfo/Etc/GMT_minus_5.py
-lib/pytz/zoneinfo/Etc/GMT_minus_6.py
-lib/pytz/zoneinfo/Etc/GMT_minus_7.py
-lib/pytz/zoneinfo/Etc/GMT_minus_8.py
-lib/pytz/zoneinfo/Etc/GMT_minus_9.py
-lib/pytz/zoneinfo/Etc/GMT_plus_0.py
-lib/pytz/zoneinfo/Etc/GMT_plus_1.py
-lib/pytz/zoneinfo/Etc/GMT_plus_10.py
-lib/pytz/zoneinfo/Etc/GMT_plus_11.py
-lib/pytz/zoneinfo/Etc/GMT_plus_12.py
-lib/pytz/zoneinfo/Etc/GMT_plus_2.py
-lib/pytz/zoneinfo/Etc/GMT_plus_3.py
-lib/pytz/zoneinfo/Etc/GMT_plus_4.py
-lib/pytz/zoneinfo/Etc/GMT_plus_5.py
-lib/pytz/zoneinfo/Etc/GMT_plus_6.py
-lib/pytz/zoneinfo/Etc/GMT_plus_7.py
-lib/pytz/zoneinfo/Etc/GMT_plus_8.py
-lib/pytz/zoneinfo/Etc/GMT_plus_9.py
-lib/pytz/zoneinfo/Etc/Greenwich.py
-lib/pytz/zoneinfo/Etc/UCT.py
-lib/pytz/zoneinfo/Etc/UTC.py
-lib/pytz/zoneinfo/Etc/Universal.py
-lib/pytz/zoneinfo/Etc/Zulu.py
-lib/pytz/zoneinfo/Etc/__init__.py
-lib/pytz/zoneinfo/Europe/Amsterdam.py
-lib/pytz/zoneinfo/Europe/Andorra.py
-lib/pytz/zoneinfo/Europe/Athens.py
-lib/pytz/zoneinfo/Europe/Belfast.py
-lib/pytz/zoneinfo/Europe/Belgrade.py
-lib/pytz/zoneinfo/Europe/Berlin.py
-lib/pytz/zoneinfo/Europe/Bratislava.py
-lib/pytz/zoneinfo/Europe/Brussels.py
-lib/pytz/zoneinfo/Europe/Bucharest.py
-lib/pytz/zoneinfo/Europe/Budapest.py
-lib/pytz/zoneinfo/Europe/Chisinau.py
-lib/pytz/zoneinfo/Europe/Copenhagen.py
-lib/pytz/zoneinfo/Europe/Dublin.py
-lib/pytz/zoneinfo/Europe/Gibraltar.py
-lib/pytz/zoneinfo/Europe/Helsinki.py
-lib/pytz/zoneinfo/Europe/Istanbul.py
-lib/pytz/zoneinfo/Europe/Kaliningrad.py
-lib/pytz/zoneinfo/Europe/Kiev.py
-lib/pytz/zoneinfo/Europe/Lisbon.py
-lib/pytz/zoneinfo/Europe/Ljubljana.py
-lib/pytz/zoneinfo/Europe/London.py
-lib/pytz/zoneinfo/Europe/Luxembourg.py
-lib/pytz/zoneinfo/Europe/Madrid.py
-lib/pytz/zoneinfo/Europe/Malta.py
-lib/pytz/zoneinfo/Europe/Mariehamn.py
-lib/pytz/zoneinfo/Europe/Minsk.py
-lib/pytz/zoneinfo/Europe/Monaco.py
-lib/pytz/zoneinfo/Europe/Moscow.py
-lib/pytz/zoneinfo/Europe/Nicosia.py
-lib/pytz/zoneinfo/Europe/Oslo.py
-lib/pytz/zoneinfo/Europe/Paris.py
-lib/pytz/zoneinfo/Europe/Prague.py
-lib/pytz/zoneinfo/Europe/Riga.py
-lib/pytz/zoneinfo/Europe/Rome.py
-lib/pytz/zoneinfo/Europe/Samara.py
-lib/pytz/zoneinfo/Europe/San_Marino.py
-lib/pytz/zoneinfo/Europe/Sarajevo.py
-lib/pytz/zoneinfo/Europe/Simferopol.py
-lib/pytz/zoneinfo/Europe/Skopje.py
-lib/pytz/zoneinfo/Europe/Sofia.py
-lib/pytz/zoneinfo/Europe/Stockholm.py
-lib/pytz/zoneinfo/Europe/Tallinn.py
-lib/pytz/zoneinfo/Europe/Tirane.py
-lib/pytz/zoneinfo/Europe/Tiraspol.py
-lib/pytz/zoneinfo/Europe/Uzhgorod.py
-lib/pytz/zoneinfo/Europe/Vaduz.py
-lib/pytz/zoneinfo/Europe/Vatican.py
-lib/pytz/zoneinfo/Europe/Vienna.py
-lib/pytz/zoneinfo/Europe/Vilnius.py
-lib/pytz/zoneinfo/Europe/Warsaw.py
-lib/pytz/zoneinfo/Europe/Zagreb.py
-lib/pytz/zoneinfo/Europe/Zaporozhye.py
-lib/pytz/zoneinfo/Europe/Zurich.py
-lib/pytz/zoneinfo/Europe/__init__.py
-lib/pytz/zoneinfo/Indian/Antananarivo.py
-lib/pytz/zoneinfo/Indian/Chagos.py
-lib/pytz/zoneinfo/Indian/Christmas.py
-lib/pytz/zoneinfo/Indian/Cocos.py
-lib/pytz/zoneinfo/Indian/Comoro.py
-lib/pytz/zoneinfo/Indian/Kerguelen.py
-lib/pytz/zoneinfo/Indian/Mahe.py
-lib/pytz/zoneinfo/Indian/Maldives.py
-lib/pytz/zoneinfo/Indian/Mauritius.py
-lib/pytz/zoneinfo/Indian/Mayotte.py
-lib/pytz/zoneinfo/Indian/Reunion.py
-lib/pytz/zoneinfo/Indian/__init__.py
-lib/pytz/zoneinfo/Mexico/BajaNorte.py
-lib/pytz/zoneinfo/Mexico/BajaSur.py
-lib/pytz/zoneinfo/Mexico/General.py
-lib/pytz/zoneinfo/Mexico/__init__.py
-lib/pytz/zoneinfo/Pacific/Apia.py
-lib/pytz/zoneinfo/Pacific/Auckland.py
-lib/pytz/zoneinfo/Pacific/Chatham.py
-lib/pytz/zoneinfo/Pacific/Easter.py
-lib/pytz/zoneinfo/Pacific/Efate.py
-lib/pytz/zoneinfo/Pacific/Enderbury.py
-lib/pytz/zoneinfo/Pacific/Fakaofo.py
-lib/pytz/zoneinfo/Pacific/Fiji.py
-lib/pytz/zoneinfo/Pacific/Funafuti.py
-lib/pytz/zoneinfo/Pacific/Galapagos.py
-lib/pytz/zoneinfo/Pacific/Gambier.py
-lib/pytz/zoneinfo/Pacific/Guadalcanal.py
-lib/pytz/zoneinfo/Pacific/Guam.py
-lib/pytz/zoneinfo/Pacific/Honolulu.py
-lib/pytz/zoneinfo/Pacific/Johnston.py
-lib/pytz/zoneinfo/Pacific/Kiritimati.py
-lib/pytz/zoneinfo/Pacific/Kosrae.py
-lib/pytz/zoneinfo/Pacific/Kwajalein.py
-lib/pytz/zoneinfo/Pacific/Majuro.py
-lib/pytz/zoneinfo/Pacific/Marquesas.py
-lib/pytz/zoneinfo/Pacific/Midway.py
-lib/pytz/zoneinfo/Pacific/Nauru.py
-lib/pytz/zoneinfo/Pacific/Niue.py
-lib/pytz/zoneinfo/Pacific/Norfolk.py
-lib/pytz/zoneinfo/Pacific/Noumea.py
-lib/pytz/zoneinfo/Pacific/Pago_Pago.py
-lib/pytz/zoneinfo/Pacific/Palau.py
-lib/pytz/zoneinfo/Pacific/Pitcairn.py
-lib/pytz/zoneinfo/Pacific/Ponape.py
-lib/pytz/zoneinfo/Pacific/Port_Moresby.py
-lib/pytz/zoneinfo/Pacific/Rarotonga.py
-lib/pytz/zoneinfo/Pacific/Saipan.py
-lib/pytz/zoneinfo/Pacific/Samoa.py
-lib/pytz/zoneinfo/Pacific/Tahiti.py
-lib/pytz/zoneinfo/Pacific/Tarawa.py
-lib/pytz/zoneinfo/Pacific/Tongatapu.py
-lib/pytz/zoneinfo/Pacific/Truk.py
-lib/pytz/zoneinfo/Pacific/Wake.py
-lib/pytz/zoneinfo/Pacific/Wallis.py
-lib/pytz/zoneinfo/Pacific/Yap.py
-lib/pytz/zoneinfo/Pacific/__init__.py
-lib/pytz/zoneinfo/SystemV/AST4.py
-lib/pytz/zoneinfo/SystemV/AST4ADT.py
-lib/pytz/zoneinfo/SystemV/CST6.py
-lib/pytz/zoneinfo/SystemV/CST6CDT.py
-lib/pytz/zoneinfo/SystemV/EST5.py
-lib/pytz/zoneinfo/SystemV/EST5EDT.py
-lib/pytz/zoneinfo/SystemV/HST10.py
-lib/pytz/zoneinfo/SystemV/MST7.py
-lib/pytz/zoneinfo/SystemV/MST7MDT.py
-lib/pytz/zoneinfo/SystemV/PST8.py
-lib/pytz/zoneinfo/SystemV/PST8PDT.py
-lib/pytz/zoneinfo/SystemV/YST9.py
-lib/pytz/zoneinfo/SystemV/YST9YDT.py
-lib/pytz/zoneinfo/SystemV/__init__.py
-lib/pytz/zoneinfo/US/Alaska.py
-lib/pytz/zoneinfo/US/Aleutian.py
-lib/pytz/zoneinfo/US/Arizona.py
-lib/pytz/zoneinfo/US/Central.py
-lib/pytz/zoneinfo/US/East_minus_Indiana.py
-lib/pytz/zoneinfo/US/Eastern.py
-lib/pytz/zoneinfo/US/Hawaii.py
-lib/pytz/zoneinfo/US/Indiana_minus_Starke.py
-lib/pytz/zoneinfo/US/Michigan.py
-lib/pytz/zoneinfo/US/Mountain.py
-lib/pytz/zoneinfo/US/Pacific.py
-lib/pytz/zoneinfo/US/Pacific_minus_New.py
-lib/pytz/zoneinfo/US/Samoa.py
-lib/pytz/zoneinfo/US/__init__.py
-lib/subprocess/__init__.py
-lib/subprocess/subprocess.py
-license/DATEUTIL_LICENSE.txt
-license/LICENSE
-license/LICENSE_BAKOMA
-license/LICENSE_COLORBREWER
-license/LICENSE_PAINT
-license/LICENSE_PIL
-license/LICENSE_YORICK
-license/LICENSE_enthought.txt
-license/PYTZ_LICENSE.txt
-src/MPL_isnan.h
-src/_backend_agg.cpp
-src/_backend_agg.h
-src/_backend_gdk.c
-src/_gtkagg.cpp
-src/_image.cpp
-src/_image.h
-src/_isnan.c
-src/_na_backend_agg.cpp
-src/_na_backend_gdk.c
-src/_na_cntr.c
-src/_na_image.cpp
-src/_na_nxutils.c
-src/_na_transforms.cpp
-src/_nc_backend_agg.cpp
-src/_nc_backend_gdk.c
-src/_nc_cntr.c
-src/_nc_image.cpp
-src/_nc_nxutils.c
-src/_nc_transforms.cpp
-src/_ns_backend_agg.cpp
-src/_ns_backend_gdk.c
-src/_ns_cntr.c
-src/_ns_image.cpp
-src/_ns_nxutils.c
-src/_ns_transforms.cpp
-src/_subprocess.c
-src/_tkagg.cpp
-src/_transforms.cpp
-src/_transforms.h
-src/_windowing.cpp
-src/_wxagg.cpp
-src/agg.cxx
-src/cntr.c
-src/ft2font.cpp
-src/ft2font.h
-src/mplutils.cpp
-src/mplutils.h
-src/numerix.h
-src/nxutils.c
-src/swig_runtime.h
-swig/agg.i
-swig/agg_basics.i
-swig/agg_buffer.h
-swig/agg_conv_curve.i
-swig/agg_conv_stroke.i
-swig/agg_conv_transform.i
-swig/agg_path_storage.i
-swig/agg_rasterizer_scanline_aa.i
-swig/agg_renderer_base.i
-swig/agg_renderer_scanline.i
-swig/agg_scanline_bin.i
-swig/agg_span_image_filter.i
-swig/agg_trans_affine.i
-swig/agg_typedefs.h
-swig/agg_typemaps.i
Modified: branches/transforms/lib/matplotlib/backend_bases.py
===================================================================
--- branches/transforms/lib/matplotlib/backend_bases.py	2007年09月12日 13:36:25 UTC (rev 3835)
+++ branches/transforms/lib/matplotlib/backend_bases.py	2007年09月12日 14:05:20 UTC (rev 3836)
@@ -1209,6 +1209,14 @@
 def get_default_filetype(self):
 raise NotImplementedError
 
+ def set_window_title(self, title):
+ """
+ Set the title text of the window containing the figure. Note that
+ this has no effect if there is no window (eg, a PS backend).
+ """
+ if hasattr(self, "manager"):
+ self.manager.set_window_title(title)
+
 def switch_backends(self, FigureCanvasClass):
 """
 instantiate an instance of FigureCanvasClass
@@ -1321,6 +1329,13 @@
 """
 pass
 
+ def set_window_title(self, title):
+ """
+ Set the title text of the window containing the figure. Note that
+ this has no effect if there is no window (eg, a PS backend).
+ """
+ pass
+
 # cursors
 class Cursors: #namespace
 HAND, POINTER, SELECT_REGION, MOVE = range(4)
Modified: branches/transforms/lib/matplotlib/backends/backend_fltkagg.py
===================================================================
--- branches/transforms/lib/matplotlib/backends/backend_fltkagg.py	2007年09月12日 13:36:25 UTC (rev 3835)
+++ branches/transforms/lib/matplotlib/backends/backend_fltkagg.py	2007年09月12日 14:05:20 UTC (rev 3836)
@@ -299,6 +299,9 @@
 self.canvas.draw()
 self.window.redraw()
 
+ def set_window_title(self, title):
+ self.window_title=title
+ self.window.label(title)
 
 class AxisMenu:
 def __init__(self, toolbar):
Modified: branches/transforms/lib/matplotlib/backends/backend_gtk.py
===================================================================
--- branches/transforms/lib/matplotlib/backends/backend_gtk.py	2007年09月12日 13:36:25 UTC (rev 3835)
+++ branches/transforms/lib/matplotlib/backends/backend_gtk.py	2007年09月12日 14:05:20 UTC (rev 3836)
@@ -460,6 +460,8 @@
 toolbar = None
 return toolbar
 
+ def set_window_title(self, title):
+ self.window.set_title(title)
 
 def resize(self, width, height):
 'set the canvas size in pixels'
Modified: branches/transforms/lib/matplotlib/backends/backend_pdf.py
===================================================================
--- branches/transforms/lib/matplotlib/backends/backend_pdf.py	2007年09月12日 13:36:25 UTC (rev 3835)
+++ branches/transforms/lib/matplotlib/backends/backend_pdf.py	2007年09月12日 14:05:20 UTC (rev 3836)
@@ -491,6 +491,7 @@
 return fontdictObject
 
 def embedType1(self, filename, fontinfo):
+ # TODO: font effects such as SlantFont
 fh = open(filename, 'rb')
 matplotlib.verbose.report(
 'Embedding Type 1 font ' + filename, 'debug')
@@ -520,8 +521,15 @@
 
 if fontinfo.encodingfile is not None:
 enc = dviread.Encoding(fontinfo.encodingfile)
- widths = [ afmdata.get_width_from_char_name(ch)
- for ch in enc ]
+ widths = []
+ for ch in enc:
+ try:
+ widths.append(afmdata.get_width_from_char_name(ch))
+ except KeyError:
+ matplotlib.verbose.report(
+ 'No width for %s in %s' % (ch, fullname), 'debug')
+ widths.append(0)
+
 differencesArray = [ Name(ch) for ch in enc ]
 differencesArray = [ 0 ] + differencesArray
 firstchar = 0
@@ -538,11 +546,24 @@
 firstchar = not_None.next()
 lastchar = max(not_None)
 widths = widths[firstchar:lastchar+1]
+ for i,w in enumerate(widths):
+ if w is None: widths[i] = 0
 
- differencesArray = [ firstchar ]
+ differencesArray = [ ]
+ need_idx = True
 for ch in range(firstchar, lastchar+1):
- differencesArray.append(Name(
- afmdata.get_name_char(ch, isord=True)))
+ try:
+ name = afmdata.get_name_char(ch, isord=True)
+ if need_idx:
+ differencesArray.append(ch)
+ need_idx = False
+ differencesArray.append(Name(name))
+ except KeyError:
+ matplotlib.verbose.report(
+ 'No name for glyph %d in %s' % (ch, fullname), 
+ 'debug')
+ need_idx = True
+
 
 fontdict = {
 'Type': Name('Font'),
@@ -1448,17 +1469,16 @@
 
 # Gather font information and do some setup for combining
 # characters into strings.
- oldfontnum, seq = None, []
- for x1, y1, fontnum, glyph, width in page.text:
- if fontnum != oldfontnum:
- texname, fontsize = dvi.fontinfo(fontnum)
- fontinfo = self.tex_font_mapping(texname)
+ oldfont, seq = None, []
+ for x1, y1, dvifont, glyph, width in page.text:
+ if dvifont != oldfont:
+ fontinfo = self.tex_font_mapping(dvifont.texname)
 pdfname = self.file.fontName(fontinfo.filename)
 self.file.fontInfo[pdfname] = Bunch(
 encodingfile=fontinfo.encoding,
 afmfile=fontinfo.afm)
- seq += [['font', pdfname, fontsize]]
- oldfontnum = fontnum
+ seq += [['font', pdfname, dvifont.size]]
+ oldfont = dvifont
 seq += [['text', x1, y1, [chr(glyph)], x1+width]]
 seq += [('end',)]
 
Modified: branches/transforms/lib/matplotlib/backends/backend_qt.py
===================================================================
--- branches/transforms/lib/matplotlib/backends/backend_qt.py	2007年09月12日 13:36:25 UTC (rev 3835)
+++ branches/transforms/lib/matplotlib/backends/backend_qt.py	2007年09月12日 14:05:20 UTC (rev 3836)
@@ -247,6 +247,9 @@
 if DEBUG: print "destroy figure manager"
 self.window.close(True)
 
+ def set_window_title(self, title):
+ self.window.setCaption(title)
+
 class NavigationToolbar2QT( NavigationToolbar2, qt.QWidget ):
 # list of toolitems to add to the toolbar, format is:
 # text, tooltip_text, image_file, callback(str)
Modified: branches/transforms/lib/matplotlib/backends/backend_qt4.py
===================================================================
--- branches/transforms/lib/matplotlib/backends/backend_qt4.py	2007年09月12日 13:36:25 UTC (rev 3835)
+++ branches/transforms/lib/matplotlib/backends/backend_qt4.py	2007年09月12日 14:05:20 UTC (rev 3836)
@@ -249,6 +249,9 @@
 if DEBUG: print "destroy figure manager"
 self.window.close()
 
+ def set_window_title(self, title):
+ self.window.setWindowTitle(title)
+
 class NavigationToolbar2QT( NavigationToolbar2, QtGui.QWidget ):
 # list of toolitems to add to the toolbar, format is:
 # text, tooltip_text, image_file, callback(str)
Modified: branches/transforms/lib/matplotlib/backends/backend_tkagg.py
===================================================================
--- branches/transforms/lib/matplotlib/backends/backend_tkagg.py	2007年09月12日 13:36:25 UTC (rev 3835)
+++ branches/transforms/lib/matplotlib/backends/backend_tkagg.py	2007年09月12日 14:05:20 UTC (rev 3836)
@@ -350,6 +350,9 @@
 pass
 self.window = None
 
+ def set_window_title(self, title):
+ self.window.wm_title(title)
+
 class AxisMenu:
 def __init__(self, master, naxes):
 self._master = master
Modified: branches/transforms/lib/matplotlib/backends/backend_wx.py
===================================================================
--- branches/transforms/lib/matplotlib/backends/backend_wx.py	2007年09月12日 13:36:25 UTC (rev 3835)
+++ branches/transforms/lib/matplotlib/backends/backend_wx.py	2007年09月12日 14:05:20 UTC (rev 3836)
@@ -1399,6 +1399,9 @@
 #wx.GetApp().ProcessIdle()
 wx.WakeUpIdle()
 
+ def set_window_title(self, title):
+ self.window.SetTitle(title)
+
 # Identifiers for toolbar controls - images_wx contains bitmaps for the images
 # used in the controls. wxWindows does not provide any stock images, so I've
 # 'stolen' those from GTK2, and transformed them into the appropriate format.
Modified: branches/transforms/lib/matplotlib/dviread.py
===================================================================
--- branches/transforms/lib/matplotlib/dviread.py	2007年09月12日 13:36:25 UTC (rev 3835)
+++ branches/transforms/lib/matplotlib/dviread.py	2007年09月12日 14:05:20 UTC (rev 3836)
@@ -9,15 +9,13 @@
 for page in dvi: # iterate over pages
 w, h, d = page.width, page.height, page.descent
 for x,y,font,glyph,width in page.text:
- fontname, pointsize = dvi.fontinfo(font)
+ fontname = font.texname
+ pointsize = font.size
 ...
 for x,y,height,width in page.boxes:
 ...
 """
 
-# TODO: support TeX virtual fonts (*.vf) which...
 
[truncated message content]
From: <md...@us...> - 2007年09月13日 12:50:07
Revision: 3847
 http://matplotlib.svn.sourceforge.net/matplotlib/?rev=3847&view=rev
Author: mdboom
Date: 2007年09月13日 05:50:05 -0700 (2007年9月13日)
Log Message:
-----------
Merged revisions 3836-3846 via svnmerge from 
http://matplotlib.svn.sf.net/svnroot/matplotlib/trunk/matplotlib
........
 r3844 | jdh2358 | 2007年09月12日 16:37:41 -0400 (2007年9月12日) | 1 line
 
 fixed a bar units bug
........
 r3845 | jouni | 2007年09月13日 02:29:14 -0400 (2007年9月13日) | 3 lines
 
 More work on dviread and usetex in pdf. It is more usable now,
 so I am renaming the method from _draw_tex to draw_tex.
........
Modified Paths:
--------------
 branches/transforms/API_CHANGES
 branches/transforms/CHANGELOG
 branches/transforms/lib/matplotlib/artist.py
 branches/transforms/lib/matplotlib/axes.py
 branches/transforms/lib/matplotlib/axis.py
 branches/transforms/lib/matplotlib/backends/backend_pdf.py
 branches/transforms/lib/matplotlib/dviread.py
 branches/transforms/lib/matplotlib/mlab.py
 branches/transforms/lib/matplotlib/patches.py
Added Paths:
-----------
 branches/transforms/examples/units/bar_demo2.py
Property Changed:
----------------
 branches/transforms/
Property changes on: branches/transforms
___________________________________________________________________
Name: svnmerge-integrated
 - /trunk/matplotlib:1-3835
 + /trunk/matplotlib:1-3846
Modified: branches/transforms/API_CHANGES
===================================================================
--- branches/transforms/API_CHANGES	2007年09月13日 12:44:16 UTC (rev 3846)
+++ branches/transforms/API_CHANGES	2007年09月13日 12:50:05 UTC (rev 3847)
@@ -1,3 +1,5 @@
+ Made skiprows=1 the default on csv2rec
+
 The gd and paint backends have been deleted.
 
 The errorbar method and function now accept additional kwargs
Modified: branches/transforms/CHANGELOG
===================================================================
--- branches/transforms/CHANGELOG	2007年09月13日 12:44:16 UTC (rev 3846)
+++ branches/transforms/CHANGELOG	2007年09月13日 12:50:05 UTC (rev 3847)
@@ -1,3 +1,10 @@
+2007年09月13日 The usetex support in the pdf backend is more usable now,
+ so I am enabling it. - JKS
+
+2007年09月12日 Fixed a Axes.bar unit bug - JDH
+
+2007年09月10日 Made skiprows=1 the default on csv2rec - JDH
+
 2007年09月09日 Split out the plotting part of pylab and put it in
 pyplot.py; removed numerix from the remaining pylab.py,
 which imports everything from pyplot.py. The intention
Copied: branches/transforms/examples/units/bar_demo2.py (from rev 3845, trunk/matplotlib/examples/units/bar_demo2.py)
===================================================================
--- branches/transforms/examples/units/bar_demo2.py	 (rev 0)
+++ branches/transforms/examples/units/bar_demo2.py	2007年09月13日 12:50:05 UTC (rev 3847)
@@ -0,0 +1,34 @@
+"""
+plot using a variety of cm vs inches conversions. The example shows
+how default unit instrospection works (ax1), how various keywords can
+be used to set the x and y units to override the defaults (ax2, ax3,
+ax4) and how one can set the xlimits using scalars (ax3, current units
+assumed) or units (conversions applied to get the numbers to current
+units)
+
+"""
+from basic_units import cm, inch
+from pylab import figure, show, nx
+
+cms = cm *nx.arange(0, 10, 2)
+bottom=0*cm
+width=0.8*cm
+
+fig = figure()
+
+ax1 = fig.add_subplot(2,2,1)
+ax1.bar(cms, cms, bottom=bottom)
+
+ax2 = fig.add_subplot(2,2,2)
+ax2.bar(cms, cms, bottom=bottom, width=width, xunits=cm, yunits=inch)
+
+ax3 = fig.add_subplot(2,2,3)
+ax3.bar(cms, cms, bottom=bottom, width=width, xunits=inch, yunits=cm)
+ax3.set_xlim(3, 6) # scalars are interpreted in current units
+
+ax4 = fig.add_subplot(2,2,4)
+ax4.bar(cms, cms, bottom=bottom, width=width, xunits=inch, yunits=inch)
+#fig.savefig('simple_conversion_plot.png')
+ax4.set_xlim(3*cm, 6*cm) # cm are converted to inches
+
+show()
Modified: branches/transforms/lib/matplotlib/artist.py
===================================================================
--- branches/transforms/lib/matplotlib/artist.py	2007年09月13日 12:44:16 UTC (rev 3846)
+++ branches/transforms/lib/matplotlib/artist.py	2007年09月13日 12:50:05 UTC (rev 3847)
@@ -51,7 +51,7 @@
 self._remove_method = None
 
 def remove(self):
- '''
+ """
 Remove the artist from the figure if possible. The effect will not
 be visible until the figure is redrawn, e.g., with ax.draw_idle().
 Call ax.relim() to update the axes limits if desired.
@@ -60,7 +60,7 @@
 was added to axes with autolim=True.
 
 Note: there is no support for removing the artist's legend entry.
- '''
+ """
 
 # There is no method to set the callback. Instead the parent should set
 # the _remove_method attribute directly. This would be a protected
Modified: branches/transforms/lib/matplotlib/axes.py
===================================================================
--- branches/transforms/lib/matplotlib/axes.py	2007年09月13日 12:44:16 UTC (rev 3846)
+++ branches/transforms/lib/matplotlib/axes.py	2007年09月13日 12:50:05 UTC (rev 3847)
@@ -1193,23 +1193,27 @@
 def _process_unit_info(self, xdata=None, ydata=None, kwargs=None):
 'look for unit kwargs and update the axis instances as necessary'
 
- if self.xaxis is None or self.xaxis is None: return
+ if self.xaxis is None or self.yaxis is None: return
 
-
+ #print 'processing', self.get_geometry()
 if xdata is not None:
 self.xaxis.update_units(xdata)
+ #print '\tset from xdata', self.xaxis.units
 
 if ydata is not None:
 self.yaxis.update_units(ydata)
+ #print '\tset from ydata', self.yaxis.units
 
 # process kwargs 2nd since these will override default units
 if kwargs is not None:
 xunits = kwargs.pop( 'xunits', self.xaxis.units)
 if xunits!=self.xaxis.units:
+ #print '\tkw setting xunits', xunits
 self.xaxis.set_units(xunits)
 
 yunits = kwargs.pop('yunits', self.yaxis.units)
 if yunits!=self.yaxis.units:
+ #print '\tkw setting yunits', yunits
 self.yaxis.set_units(yunits)
 
 def in_axes(self, xwin, ywin):
@@ -3122,11 +3126,13 @@
 else:
 raise ValueError, 'invalid orientation: %s' % orientation
 
- left = npy.asarray(left)
- height = npy.asarray(height)
- width = npy.asarray(width)
- bottom = npy.asarray(bottom)
 
+ # do not convert to array here as unit info is lost
+ #left = npy.asarray(left)
+ #height = npy.asarray(height)
+ #width = npy.asarray(width)
+ #bottom = npy.asarray(bottom)
+
 if len(linewidth) == 1: linewidth = linewidth * nbars
 
 # if color looks like a color string, an RGB tuple or a
@@ -3169,14 +3175,14 @@
 # lets do some conversions now
 if self.xaxis is not None:
 xconv = self.xaxis.converter
- if ( xconv ):
+ if xconv is not None:
 units = self.xaxis.get_units()
 left = xconv.convert( left, units )
 width = xconv.convert( width, units )
 
 if self.yaxis is not None:
 yconv = self.yaxis.converter
- if ( yconv ):
+ if yconv is not None :
 units = self.yaxis.get_units()
 bottom = yconv.convert( bottom, units )
 height = yconv.convert( height, units )
@@ -3216,12 +3222,14 @@
 
 if xerr is not None or yerr is not None:
 if orientation == 'vertical':
- x = left + 0.5*width
- y = bottom + height
+ # using list comps rather than arrays to preserve unit info
+ x = [l+0.5*w for l, w in zip(left, width)]
+ y = [b+h for b,h in zip(bottom, height)]
 
 elif orientation == 'horizontal':
- x = left + width
- y = bottom + 0.5*height
+ # using list comps rather than arrays to preserve unit info
+ x = [l+w for l,w in zip(left, width)]
+ y = [b+0.5*h for b,h in zip(bottom, height)]
 
 self.errorbar(
 x, y,
Modified: branches/transforms/lib/matplotlib/axis.py
===================================================================
--- branches/transforms/lib/matplotlib/axis.py	2007年09月13日 12:44:16 UTC (rev 3846)
+++ branches/transforms/lib/matplotlib/axis.py	2007年09月13日 12:50:05 UTC (rev 3847)
@@ -821,7 +821,7 @@
 return x
 
 ret = self.converter.convert(x, self.units)
- #print 'convert_units converting: units=%s, converter=%s, in=%s, out=%s'%(self.units, self.converter, x, ret)
+ #print 'convert_units converting: axis=%s, units=%s, converter=%s, in=%s, out=%s'%(self, self.units, self.converter, x, ret)
 return ret
 
 def set_units(self, u):
Modified: branches/transforms/lib/matplotlib/backends/backend_pdf.py
===================================================================
--- branches/transforms/lib/matplotlib/backends/backend_pdf.py	2007年09月13日 12:44:16 UTC (rev 3846)
+++ branches/transforms/lib/matplotlib/backends/backend_pdf.py	2007年09月13日 12:50:05 UTC (rev 3847)
@@ -527,7 +527,7 @@
 widths.append(afmdata.get_width_from_char_name(ch))
 except KeyError:
 matplotlib.verbose.report(
- 'No width for %s in %s' % (ch, fullname), 'debug')
+ 'No width for %s in %s' % (ch, fullname), 'debug-annoying')
 widths.append(0)
 
 differencesArray = [ Name(ch) for ch in enc ]
@@ -561,7 +561,7 @@
 except KeyError:
 matplotlib.verbose.report(
 'No name for glyph %d in %s' % (ch, fullname), 
- 'debug')
+ 'debug-annoying')
 need_idx = True
 
 
@@ -1449,9 +1449,7 @@
 # Pop off the global transformation
 self.file.output(Op.grestore)
 
- def _draw_tex(self, gc, x, y, s, prop, angle):
- # Rename to draw_tex to enable
-
+ def draw_tex(self, gc, x, y, s, prop, angle):
 texmanager = self.get_texmanager()
 fontsize = prop.get_size_in_points()
 dvifile = texmanager.make_dvi(s, fontsize)
@@ -1494,7 +1492,7 @@
 elt[3][-1] += next[3][0]
 elt[4] += next[4]-next[1]
 else:
- elt[3] += [offset, next[3][0]]
+ elt[3] += [offset*1000.0/dvifont.size, next[3][0]]
 elt[4] = next[4]
 del seq[i+1]
 continue
Modified: branches/transforms/lib/matplotlib/dviread.py
===================================================================
--- branches/transforms/lib/matplotlib/dviread.py	2007年09月13日 12:44:16 UTC (rev 3846)
+++ branches/transforms/lib/matplotlib/dviread.py	2007年09月13日 12:50:05 UTC (rev 3847)
@@ -84,16 +84,22 @@
 e = 0 # zero depth
 else: # glyph
 x,y,font,g,w = elt
- h = (font.scale * font.tfm.height[g]) >> 20
- e = (font.scale * font.tfm.depth[g]) >> 20
+ h = _mul2012(font._scale, font._tfm.height[g])
+ e = _mul2012(font._scale, font._tfm.depth[g])
 minx = min(minx, x)
 miny = min(miny, y - h)
 maxx = max(maxx, x + w)
 maxy = max(maxy, y + e)
 maxy_pure = max(maxy_pure, y)
 
+ if self.dpi is None:
+ # special case for ease of debugging: output raw dvi coordinates
+ return mpl_cbook.Bunch(text=self.text, boxes=self.boxes,
+ width=maxx-minx, height=maxy_pure-miny,
+ descent=maxy-maxy_pure)
+
 d = self.dpi / (72.27 * 2**16) # from TeX's "scaled points" to dpi units
- text = [ ((x-minx)*d, (maxy-y)*d, DviFont(f), g, w*d) 
+ text = [ ((x-minx)*d, (maxy-y)*d, f, g, w*d) 
 for (x,y,f,g,w) in self.text ]
 boxes = [ ((x-minx)*d, (maxy-y)*d, h*d, w*d) for (x,y,h,w) in self.boxes ]
 
@@ -110,11 +116,11 @@
 while True:
 byte = ord(self.file.read(1))
 self._dispatch(byte)
- if self.state == _dvistate.inpage:
- matplotlib.verbose.report(
- 'Dvi._read: after %d at %f,%f' % 
- (byte, self.h, self.v), 
- 'debug-annoying')
+# if self.state == _dvistate.inpage:
+# matplotlib.verbose.report(
+# 'Dvi._read: after %d at %f,%f' % 
+# (byte, self.h, self.v), 
+# 'debug-annoying')
 if byte == 140: # end of page
 return True
 if self.state == _dvistate.post_post: # end of file
@@ -225,21 +231,11 @@
 # I think we can assume this is constant
 self.state = _dvistate.outer
 
- def _width_of(self, char, font):
- width = font.tfm.width.get(char, None)
- if width is not None:
- return (width * font.scale) >> 20
-
- matplotlib.verbose.report(
- 'No width for char %d in font %s' % (char, font.name),
- 'debug')
- return 0
-
 def _set_char(self, char):
 if self.state != _dvistate.inpage:
 raise ValueError, "misplaced set_char in dvi file"
 self._put_char(char)
- self.h += self._width_of(char, self.fonts[self.f])
+ self.h += self.fonts[self.f]._width_of(char)
 
 def _set_rule(self, a, b):
 if self.state != _dvistate.inpage:
@@ -251,20 +247,33 @@
 if self.state != _dvistate.inpage:
 raise ValueError, "misplaced put_char in dvi file"
 font = self.fonts[self.f]
- if font.vf is None:
+ if font._vf is None:
 self.text.append((self.h, self.v, font, char, 
- self._width_of(char, font)))
+ font._width_of(char)))
+# matplotlib.verbose.report(
+# 'Dvi._put_char: %d,%d %d' %(self.h, self.v, char), 
+# 'debug-annoying')
 else:
- self.text.extend([(self.h + x, self.v + y, f, g, w)
- for x, y, f, g, w in font.vf[char].text])
- self.boxes.extend([(self.h + x, self.v + y, a, b)
- for x, y, a, b in font.vf[char].boxes])
+ scale = font._scale
+ for x, y, f, g, w in font._vf[char].text:
+ newf = DviFont(scale=_mul2012(scale, f._scale),
+ tfm=f._tfm, texname=f.texname, vf=f._vf)
+ self.text.append((self.h + _mul2012(x, scale),
+ self.v + _mul2012(y, scale),
+ newf, g, newf._width_of(g)))
+ self.boxes.extend([(self.h + _mul2012(x, scale),
+ self.v + _mul2012(y, scale),
+ _mul2012(a, scale), _mul2012(b, scale))
+ for x, y, a, b in font._vf[char].boxes])
 
 def _put_rule(self, a, b):
 if self.state != _dvistate.inpage:
 raise ValueError, "misplaced put_rule in dvi file"
 if a > 0 and b > 0:
 self.boxes.append((self.h, self.v, a, b))
+# matplotlib.verbose.report(
+# 'Dvi._put_rule: %d,%d %d,%d' % (self.h, self.v, a, b),
+# 'debug-annoying')
 
 def _nop(self):
 pass
@@ -357,7 +366,7 @@
 
 vf = _vffile(n[-l:])
 
- self.fonts[k] = mpl_cbook.Bunch(scale=s, tfm=tfm, name=n, vf=vf)
+ self.fonts[k] = DviFont(scale=s, tfm=tfm, texname=n, vf=vf)
 
 def _post(self):
 if self.state != _dvistate.outer:
@@ -370,17 +379,20 @@
 raise NotImplementedError
 
 class DviFont(object):
- __slots__ = ('texname', 'size')
+ """
+ Object that holds a font's texname and size and supports comparison.
+ There are also internal attributes (for use by dviread.py) that
+ are _not_ used for comparison.
 
- def __init__(self, f):
- """
- Object that holds a font's texname and size and supports comparison.
+ The size is in Adobe points (converted from TeX points).
+ """
+ __slots__ = ('texname', 'size', '_scale', '_vf', '_tfm')
 
- The size is in Adobe points (converted from TeX points).
- """
+ def __init__(self, scale, tfm, texname, vf):
+ self._scale, self._tfm, self.texname, self._vf = \
+ scale, tfm, texname, vf
 # TODO: would it make more sense to have the size in dpi units?
- self.texname = f.name
- self.size = f.scale * (72.0 / (72.27 * 2**16))
+ self.size = scale * (72.0 / (72.27 * 2**16))
 
 def __eq__(self, other):
 return self.__class__ == other.__class__ and \
@@ -389,6 +401,16 @@
 def __ne__(self, other):
 return not self.__eq__(other)
 
+ def _width_of(self, char):
+ width = self._tfm.width.get(char, None)
+ if width is not None:
+ return _mul2012(width, self._scale)
+
+ matplotlib.verbose.report(
+ 'No width for char %d in font %s' % (char, self.texname),
+ 'debug')
+ return 0
+
 class Vf(Dvi):
 """
 A virtual font (*.vf file) containing subroutines for dvi files.
@@ -465,7 +487,8 @@
 raise ValueError, "pre command in middle of vf file"
 if i != 202:
 raise ValueError, "Unknown vf format %d" % i
- matplotlib.verbose.report('vf file comment: ' + x, 'debug')
+ if len(x):
+ matplotlib.verbose.report('vf file comment: ' + x, 'debug')
 self.state = _dvistate.outer
 # cs = checksum, ds = design size
 
@@ -474,7 +497,7 @@
 if self._first_font is None:
 self._first_font = k
 
-def fix2comp(num):
+def _fix2comp(num):
 """
 Convert from two's complement to negative.
 """
@@ -484,6 +507,13 @@
 else:
 return num
 
+def _mul2012(num1, num2):
+ """
+ Multiply two numbers in 20.12 fixed point format.
+ """
+ # Separated into a function because >> has surprising precedence
+ return (num1*num2) >> 20
+
 class Tfm(object):
 """
 A TeX Font Metric file. This implementation covers only the bare
@@ -497,6 +527,7 @@
 (this is a dict because indexing may not start from 0)
 height[i], depth[i]: height and depth of character #i
 """
+ __slots__ = ('checksum', 'design_size', 'width', 'height', 'depth')
 
 def __init__(self, filename):
 matplotlib.verbose.report('opening tfm file ' + filename, 'debug')
@@ -525,9 +556,9 @@
 [ struct.unpack('!%dI' % (len(x)/4), x) 
 for x in (widths, heights, depths) ]
 for i in range(ec-bc):
- self.width[bc+i] = fix2comp(widths[ord(char_info[4*i])])
- self.height[bc+i] = fix2comp(heights[ord(char_info[4*i+1]) >> 4])
- self.depth[bc+i] = fix2comp(depths[ord(char_info[4*i+1]) & 0xf])
+ self.width[bc+i] = _fix2comp(widths[ord(char_info[4*i])])
+ self.height[bc+i] = _fix2comp(heights[ord(char_info[4*i+1]) >> 4])
+ self.depth[bc+i] = _fix2comp(depths[ord(char_info[4*i+1]) & 0xf])
 
 
 class PsfontsMap(object):
@@ -552,6 +583,7 @@
 the pdf-related files perhaps only avoid the "Base 14" pdf fonts.
 But the user may have configured these files differently.
 """
+ __slots__ = ('_font',)
 
 def __init__(self, filename):
 self._font = {}
@@ -627,7 +659,17 @@
 encoding=encoding, filename=filename)
 
 class Encoding(object):
+ """
+ Parses a *.enc file referenced from a psfonts.map style file.
+ The format this class understands is a very limited subset of
+ PostScript.
 
+ Usage (subject to change):
+ for name in Encoding(filename): 
+ whatever(name)
+ """
+ __slots__ = ('encoding',)
+
 def __init__(self, filename):
 file = open(filename, 'rt')
 try:
@@ -694,6 +736,10 @@
 
 return result
 
+# With multiple text objects per figure (e.g. tick labels) we may end
+# up reading the same tfm and vf files many times, so we implement a
+# simple cache. TODO: is this worth making persistent?
+
 _tfmcache = {}
 _vfcache = {}
 
@@ -721,19 +767,22 @@
 
 
 if __name__ == '__main__':
- matplotlib.verbose.set_level('debug')
- dvi = Dvi('foo.dvi', 72)
+ import sys
+ matplotlib.verbose.set_level('debug-annoying')
+ fname = sys.argv[1]
+ try: dpi = float(sys.argv[2])
+ except IndexError: dpi = None
+ dvi = Dvi(fname, dpi)
 fontmap = PsfontsMap(find_tex_file('pdftex.map'))
- for text,boxes in dvi:
+ for page in dvi:
 print '=== new page ==='
 fPrev = None
- for x,y,f,c in text:
- texname = dvi.fonts[f].name
- print x,y,c,chr(c),texname
+ for x,y,f,c,w in page.text:
 if f != fPrev:
- print 'font', texname, '=', fontmap[texname].__dict__
+ print 'font', f.texname, 'scaled', f._scale/pow(2.0,20)
 fPrev = f
- for x,y,w,h in boxes:
+ print x,y,c, 32 <= c < 128 and chr(c) or '.', w
+ for x,y,w,h in page.boxes:
 print x,y,'BOX',w,h
 
 
Modified: branches/transforms/lib/matplotlib/mlab.py
===================================================================
--- branches/transforms/lib/matplotlib/mlab.py	2007年09月13日 12:44:16 UTC (rev 3846)
+++ branches/transforms/lib/matplotlib/mlab.py	2007年09月13日 12:50:05 UTC (rev 3847)
@@ -1253,9 +1253,9 @@
 if r==1 or c==1:
 X.shape = max(r,c),
 if unpack: return X.transpose()
- return X
+ else: return X
 
-def csv2rec(fname, comments='#', skiprows=0, checkrows=5, delimiter=',',
+def csv2rec(fname, comments='#', skiprows=1, checkrows=5, delimiter=',',
 converterd=None, names=None, missing=None):
 """
 Load data from comma/space/tab delimited file in fname into a
Modified: branches/transforms/lib/matplotlib/patches.py
===================================================================
--- branches/transforms/lib/matplotlib/patches.py	2007年09月13日 12:44:16 UTC (rev 3846)
+++ branches/transforms/lib/matplotlib/patches.py	2007年09月13日 12:50:05 UTC (rev 3847)
@@ -77,6 +77,8 @@
 if len(kwargs): artist.setp(self, **kwargs)
 __init__.__doc__ = cbook.dedent(__init__.__doc__) % artist.kwdocd
 
+
+
 def contains(self, mouseevent):
 """Test whether the mouse event occurred in the patch.
 
@@ -352,7 +354,6 @@
 Return the vertices of the rectangle
 """
 x, y = self.xy
-
 left, right = self.convert_xunits((x, x + self.width))
 bottom, top = self.convert_yunits((y, y + self.height))
 
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
From: <md...@us...> - 2007年09月14日 13:03:33
Revision: 3851
 http://matplotlib.svn.sourceforge.net/matplotlib/?rev=3851&view=rev
Author: mdboom
Date: 2007年09月14日 06:03:31 -0700 (2007年9月14日)
Log Message:
-----------
Removed transforms on the C++ side -- removed many methods that depend
on it in backend_agg in preparation for path generalization. 
Lots of general renaming...
Modified Paths:
--------------
 branches/transforms/lib/matplotlib/artist.py
 branches/transforms/lib/matplotlib/axes.py
 branches/transforms/lib/matplotlib/axis.py
 branches/transforms/lib/matplotlib/backends/backend_agg.py
 branches/transforms/lib/matplotlib/figure.py
 branches/transforms/lib/matplotlib/finance.py
 branches/transforms/lib/matplotlib/legend.py
 branches/transforms/lib/matplotlib/lines.py
 branches/transforms/lib/matplotlib/table.py
 branches/transforms/lib/matplotlib/text.py
 branches/transforms/lib/matplotlib/ticker.py
 branches/transforms/lib/matplotlib/widgets.py
 branches/transforms/setup.py
 branches/transforms/setupext.py
 branches/transforms/src/_backend_agg.cpp
 branches/transforms/src/_backend_agg.h
 branches/transforms/src/_gtkagg.cpp
 branches/transforms/src/_tkagg.cpp
Added Paths:
-----------
 branches/transforms/lib/matplotlib/transforms.py
Removed Paths:
-------------
 branches/transforms/lib/matplotlib/affine.py
 branches/transforms/src/_transforms.cpp
 branches/transforms/src/_transforms.h
Deleted: branches/transforms/lib/matplotlib/affine.py
===================================================================
--- branches/transforms/lib/matplotlib/affine.py	2007年09月14日 12:24:20 UTC (rev 3850)
+++ branches/transforms/lib/matplotlib/affine.py	2007年09月14日 13:03:31 UTC (rev 3851)
@@ -1,854 +0,0 @@
-"""
-A set of classes to handle transformations.
-
-2007 Michael Droettboom
-"""
-
-import numpy as npy
-from numpy.linalg import inv
-from sets import Set
-
-# MGDTODO: The name of this module is bad, since it deals with
-# non-affine transformations as well. It should probably just be
-# "transforms", but we already had one of those... ;)
-
-# MGDTODO: This creates a ton of cyclical references. We may want to
-# consider using weak references
-
-# MGDTODO: deep copying is probably incorrect wrt the parent/child
-# relationships
-
-class TransformNode(object):
- def __init__(self):
- self._parents = Set()
- 
- def invalidate(self):
- if not self._do_invalidation():
- for parent in self._parents:
- parent.invalidate()
-
- def _do_invalidation(self):
- return False
-
- def set_children(self, children):
- for child in children:
- getattr(self, child)._parents.add(self)
- self._children = children
-
-# def replace_child(self, index, child):
-# children = self._children
-# getattr(self, children[index])._parents.remove(self)
-# setattr(self, children[index], child)
-# # We have to reset children in case two or more
-# # of the children are the same
-# for child in children:
-# getattr(self, child)._parents.add(self)
-# self.invalidate()
- 
-class BboxBase(TransformNode):
- '''
- This is the read-only part of a bounding-box
- '''
- 
- def __init__(self):
- TransformNode.__init__(self)
- 
- def __array__(self):
- return self.get_points()
- 
- # MGDTODO: Probably a more efficient ways to do this...
- def _get_xmin(self):
- return self.get_points()[0, 0]
- xmin = property(_get_xmin)
- 
- def _get_ymin(self):
- return self.get_points()[0, 1]
- ymin = property(_get_ymin)
-
- def _get_xmax(self):
- return self.get_points()[1, 0]
- xmax = property(_get_xmax)
-
- def _get_ymax(self):
- return self.get_points()[1, 1]
- ymax = property(_get_ymax)
-
- def _get_min(self):
- return self.get_points()[0]
- min = property(_get_min)
- 
- def _get_max(self):
- return self.get_points()[1]
- max = property(_get_max)
- 
- def _get_intervalx(self):
- return self.get_points()[:, 0]
- intervalx = property(_get_intervalx)
-
- def _get_intervaly(self):
- return self.get_points()[:, 1]
- intervaly = property(_get_intervaly)
- 
- def _get_width(self):
- return self.xmax - self.xmin
- width = property(_get_width)
-
- def _get_height(self):
- return self.ymax - self.ymin
- height = property(_get_height)
-
- def _get_bounds(self):
- return (self.xmin, self.ymin,
- self.xmax - self.xmin, self.ymax - self.ymin)
- bounds = property(_get_bounds)
-
- def get_points(self):
- return NotImplementedError()
-
- # MGDTODO: Optimize
- def containsx(self, x):
- return x >= self.xmin and x <= self.xmax
-
- def containsy(self, y):
- return y >= self.ymin and y <= self.ymax
- 
- def contains(self, x, y):
- return self.containsx(x) and self.containsy(y)
-
- def overlapsx(self, other):
- return self.containsx(other.xmin) \
- or self.containsx(other.xmax)
-
- def overlapsy(self, other):
- return self.containsy(other.ymin) \
- or self.containsx(other.ymax)
- 
- def overlaps(self, other):
- return self.overlapsx(other) \
- and self.overlapsy(other)
- 
- def fully_containsx(self, x):
- return x > self.xmin and x < self.xmax
-
- def fully_containsy(self, y):
- return y > self.ymin and y < self.ymax
- 
- def fully_contains(self, x, y):
- return self.fully_containsx(x) \
- and self.fully_containsy(y)
-
- def fully_overlapsx(self, other):
- return self.fully_containsx(other.xmin) \
- or self.fully_containsx(other.xmax)
-
- def fully_overlapsy(self, other):
- return self.fully_containsy(other.ymin) \
- or self.fully_containsx(other.ymax)
- 
- def fully_overlaps(self, other):
- return self.fully_overlapsx(other) and \
- self.fully_overlapsy(other)
-
- 
-class Bbox(BboxBase):
- def __init__(self, points):
- BboxBase.__init__(self)
- self._points = npy.asarray(points, npy.float_)
-
- #@staticmethod
- def unit():
- return Bbox.from_lbrt(0., 0., 1., 1.)
- unit = staticmethod(unit)
-
- #@staticmethod
- def from_lbwh(left, bottom, width, height):
- return Bbox.from_lbrt(left, bottom, left + width, bottom + height)
- from_lbwh = staticmethod(from_lbwh)
-
- #@staticmethod
- def from_lbrt(*args):
- points = npy.array(args, dtype=npy.float_).reshape(2, 2)
- return Bbox(points)
- from_lbrt = staticmethod(from_lbrt)
- 
- def __copy__(self):
- return Bbox(self._points.copy())
-
- def __deepcopy__(self, memo):
- return Bbox(self._points.copy())
- 
- def __cmp__(self, other):
- # MGDTODO: Totally suboptimal
- if isinstance(other, Bbox) and (self._points == other._points).all():
- return 0
- return -1
-
- def __repr__(self):
- return 'Bbox(%s)' % repr(self._points)
- __str__ = __repr__
-
- # JDH: the update method will update the box limits from the
- # existing limits and the new data; it appears here you are just
- # using the new data. We use an "ignore" flag to specify whether
- # you want to include the existing data or not in the update
- def update_from_data(self, x, y, ignore=True):
- self._points = npy.array(
- [[x.min(), y.min()], [x.max(), y.max()]],
- npy.float_)
- self.invalidate()
-
- # MGDTODO: Probably a more efficient ways to do this...
- def _set_xmin(self, val):
- self._points[0, 0] = val
- self.invalidate()
- xmin = property(BboxBase._get_xmin, _set_xmin)
-
- def _set_ymin(self, val):
- self._points[0, 1] = val
- self.invalidate()
- ymin = property(BboxBase._get_ymin, _set_ymin)
-
- def _set_xmax(self, val):
- self._points[1, 0] = val
- self.invalidate()
- xmax = property(BboxBase._get_xmax, _set_xmax)
-
- def _set_ymax(self, val):
- self._points[1, 1] = val
- self.invalidate()
- ymax = property(BboxBase._get_ymax, _set_ymax)
-
- def _set_min(self, val):
- self._points[0] = val
- self.invalidate()
- min = property(BboxBase._get_min, _set_min)
- 
- def _set_max(self, val):
- self._points[1] = val
- self.invalidate()
- max = property(BboxBase._get_max, _set_max)
- 
- def _set_intervalx(self, interval):
- self._points[:, 0] = interval
- self.invalidate()
- intervalx = property(BboxBase._get_intervalx, _set_intervalx)
-
- def _set_intervaly(self, interval):
- self._points[:, 1] = interval
- self.invalidate()
- intervaly = property(BboxBase._get_intervaly, _set_intervaly)
-
- def _set_bounds(self, bounds):
- l,b,w,h = bounds
- self._points = npy.array([[l, b], [l+w, b+h]], npy.float_)
- self.invalidate()
- bounds = property(BboxBase._get_bounds, _set_bounds)
-
- def get_points(self):
- return self._points
-
- def set_points(self, points):
- self._points = points
- self.invalidate()
-
- def set(self, other):
- self._points = other.get_points()
- self.invalidate()
- 
- def transformed(self, transform):
- return Bbox(transform(self._points))
-
- def inverse_transformed(self, transform):
- return Bbox(transform.inverted()(self._points))
- 
- def expanded(self, sw, sh):
- width = self.width
- height = self.height
- deltaw = (sw * width - width) / 2.0
- deltah = (sh * height - height) / 2.0
- a = npy.array([[-deltaw, -deltah], [deltaw, deltah]])
- return Bbox(self._points + a)
-
- #@staticmethod
- def union(bboxes):
- """
- Return the Bbox that bounds all bboxes
- """
- assert(len(bboxes))
-
- if len(bboxes) == 1:
- return bboxes[0]
-
- bbox = bboxes[0]
- xmin = bbox.xmin
- ymin = bbox.ymin
- xmax = bbox.xmax
- ymax = bbox.ymax
-
- for bbox in bboxes[1:]:
- xmin = min(xmin, bbox.xmin)
- ymin = min(ymin, bbox.ymin)
- xmax = max(xmax, bbox.xmax)
- ymax = max(ymax, bbox.ymax)
-
- return Bbox.from_lbrt(xmin, ymin, xmax, ymax)
- union = staticmethod(union)
-
-class TransformedBbox(BboxBase):
- def __init__(self, bbox, transform):
- assert isinstance(bbox, Bbox)
- assert isinstance(transform, Transform)
-
- BboxBase.__init__(self)
- self.bbox = bbox
- self.transform = transform
- self.set_children(['bbox', 'transform'])
- self._points = None
-
- def __repr__(self):
- return "TransformedBbox(%s, %s)" % (self.bbox, self.transform)
- __str__ = __repr__
- 
- def _do_invalidation(self):
- self._points = None
-
- def get_points(self):
- if self._points is None:
- self._points = self.transform(self.bbox.get_points())
- return self._points
-
-# MGDTODO: This code probably works, but I don't think it's a good idea
-# (from a code clarity perspective)
-# class BlendedBbox(BboxBase):
-# def __init__(self, bbox_x, bbox_y):
-# assert isinstance(bbox_x, BboxBase)
-# assert isinstance(bbox_y, BboxBase)
-
-# BboxBase.__init__(self)
-# self._x = bbox_x
-# self._y = bbox_y
-# self.set_children(['_x', '_y'])
-# self._points = None
-
-# def __repr__(self):
-# return "TransformedBbox(%s, %s)" % (self.bbox, self.transform)
-# __str__ = __repr__
- 
-# def _do_invalidation(self):
-# self._points = None
-
-# def get_points(self):
-# if self._points is None:
-# # MGDTODO: Optimize
-# if self._x == self._y:
-# self._points = self._x.get_points()
-# else:
-# x_points = self._x.get_points()
-# y_points = self._y.get_points()
-# self._points = npy.array(
-# [[x_points[0,0], y_points[0,1]],
-# [x_points[1,0], y_points[1,1]]],
-# npy.float_)
-# return self._points
-
-# def _set_intervalx(self, pair):
-# # MGDTODO: Optimize
-# bbox = Bbox([[pair[0], 0.0], [pair[1], 0.0]])
-# self.replace_child(0, bbox)
-# intervalx = property(BboxBase._get_intervalx, _set_intervalx)
-
-# def _set_intervaly(self, pair):
-# # MGDTODO: Optimize
-# bbox = Bbox([[0.0, pair[0]], [0.0, pair[1]]])
-# self.replace_child(1, bbox)
-# intervaly = property(BboxBase._get_intervaly, _set_intervaly)
- 
-class Transform(TransformNode):
- def __init__(self):
- TransformNode.__init__(self)
- 
- def __call__(self, points):
- raise NotImplementedError()
-
- def __add__(self, other):
- if isinstance(other, Transform):
- return composite_transform_factory(self, other)
- raise TypeError(
- "Can not add Transform to object of type '%s'" % type(other))
-
- def __radd__(self, other):
- if isinstance(other, Transform):
- return composite_transform_factory(other, self)
- raise TypeError(
- "Can not add Transform to object of type '%s'" % type(other))
-
- def transform_point(self, point):
- return self.__call__(npy.asarray([point]))[0]
- 
- def has_inverse(self):
- raise NotImplementedError()
- 
- def inverted(self):
- raise NotImplementedError()
-
- def is_separable(self):
- return False
-
- def is_affine(self):
- return False
-
-class Affine2DBase(Transform):
- input_dims = 2
- output_dims = 2
-
- def __init__(self):
- Transform.__init__(self)
- self._inverted = None
-
- def _do_invalidation(self):
- result = self._inverted is None
- self._inverted = None
- return result
-
- #@staticmethod
- def _concat(a, b):
- return npy.dot(b, a)
- _concat = staticmethod(_concat)
-
- #@staticmethod
- def concat(a, b):
- return Affine2D(Affine2D._concat(a.get_matrix(), b.get_matrix()))
- concat = staticmethod(concat)
- 
- def to_values(self):
- mtx = self.get_matrix()
- return tuple(mtx[:2].swapaxes(0, 1).flatten())
- 
- #@staticmethod
- def matrix_from_values(a, b, c, d, e, f):
- affine = npy.zeros((3, 3), npy.float_)
- affine[0, ] = a, c, e
- affine[1, ] = b, d, f
- affine[2, 2] = 1
- return affine
- matrix_from_values = staticmethod(matrix_from_values)
-
- def get_matrix(self):
- raise NotImplementedError()
- 
- def __call__(self, points):
- """
- Applies the transformation to an array of 2D points and
- returns the result.
-
- points must be a numpy array of shape (N, 2), where N is the
- number of points.
- """
- # MGDTODO: The major speed trap here is just converting to
- # the points to an array in the first place. If we can use
- # more arrays upstream, that should help here.
- if not isinstance(points, npy.ndarray):
- import traceback
- print '-' * 60
- print 'A non-numpy array was passed in for transformation. Please '
- print 'correct this.'
- print "".join(traceback.format_stack())
- print points
- mtx = self.get_matrix()
- points = npy.asarray(points, npy.float_)
- points = points.transpose()
- points = npy.dot(mtx[0:2, 0:2], points)
- points = points + mtx[0:2, 2:]
- return points.transpose()
- 
- def inverted(self):
- if self._inverted is None:
- mtx = self.get_matrix()
- self._inverted = Affine2D(inv(mtx))
- return self._inverted
- 
- def is_separable(self):
- mtx = self.get_matrix()
- return mtx[0, 1] == 0.0 and mtx[1, 0] == 0.0
-
- def is_affine(self):
- return True
-
- 
-class Affine2D(Affine2DBase):
- input_dims = 2
- output_dims = 2
- 
- def __init__(self, matrix = None):
- """
- Initialize an Affine transform from a 3x3 numpy float array.
-
- a c e
- b d f
- 0 0 1
- """
- Affine2DBase.__init__(self)
- if matrix is None:
- matrix = npy.identity(3)
- else:
- assert matrix.shape == (3, 3)
- self._mtx = matrix
- self._inverted = None
-
- def __repr__(self):
- return "Affine2D(%s)" % repr(self._mtx)
- __str__ = __repr__
-
- def __cmp__(self, other):
- if (isinstance(other, Affine2D) and
- (self.get_matrix() == other.get_matrix()).all()):
- return 0
- return -1
- 
- def __copy__(self):
- return Affine2D(self._mtx.copy())
- 
- def __deepcopy__(self, memo):
- return Affine2D(self._mtx.copy())
- 
- #@staticmethod
- def from_values(a, b, c, d, e, f):
- return Affine2D(Affine2D.matrix_from_values(a, b, c, d, e, f))
- from_values = staticmethod(from_values)
-
- def get_matrix(self):
- return self._mtx
-
- def set_matrix(self, mtx):
- self._mtx = mtx
- self.invalidate()
-
- def set(self, other):
- self._mtx = other.get_matrix()
- self.invalidate()
- 
- #@staticmethod
- def identity():
- return Affine2D(npy.identity(3))
- identity = staticmethod(identity)
-
- def clear(self):
- self._mtx = npy.identity(3)
- self.invalidate()
- return self
- 
- def rotate(self, theta):
- a = npy.cos(theta)
- b = npy.sin(theta)
- rotate_mtx = self.matrix_from_values(a, b, -b, a, 0, 0)
- self._mtx = self._concat(self._mtx, rotate_mtx)
- self.invalidate()
- return self
-
- def rotate_deg(self, degrees):
- return self.rotate(degrees*npy.pi/180.)
-
- def rotate_around(self, x, y, theta):
- return self.translate(-x, -y).rotate(theta).translate(x, y)
-
- def rotate_deg_around(self, x, y, degrees):
- return self.translate(-x, -y).rotate_deg(degrees).translate(x, y)
- 
- def translate(self, tx, ty):
- translate_mtx = self.matrix_from_values(1., 0., 0., 1., tx, ty)
- self._mtx = self._concat(self._mtx, translate_mtx)
- self.invalidate()
- return self
-
- def scale(self, sx, sy=None):
- if sy is None:
- sy = sx
- scale_mtx = self.matrix_from_values(sx, 0., 0., sy, 0., 0.)
- self._mtx = self._concat(self._mtx, scale_mtx)
- self.invalidate()
- return self
-
- def inverted(self):
- if self._inverted is None:
- mtx = self.get_matrix()
- self._inverted = Affine2D(inv(mtx))
- return self._inverted
- 
- def is_separable(self):
- mtx = self.get_matrix()
- return mtx[0, 1] == 0.0 and mtx[1, 0] == 0.0
-
- def is_affine(self):
- return True
- 
-class BlendedTransform(Transform):
- def __init__(self, x_transform, y_transform):
- assert x_transform.is_separable()
- assert y_transform.is_separable()
-
- Transform.__init__(self)
- self._x = x_transform
- self._y = y_transform
- self.set_children(['_x', '_y'])
-
- def __call__(self, points):
- if self._x == self._y:
- return self._x(points)
- 
- x_points = self._x(points)
- y_points = self._y(points)
- # This works because we already know the transforms are
- # separable
- return npy.hstack((x_points[:, 0:1], y_points[:, 1:2]))
-
-# def set_x_transform(self, x_transform):
-# self.replace_child(0, x_transform)
-
-# def set_y_transform(self, y_transform):
-# self.replace_child(1, y_transform)
- 
-class BlendedAffine2D(Affine2DBase, BlendedTransform):
- def __init__(self, x_transform, y_transform):
- assert x_transform.is_affine()
- assert y_transform.is_affine()
- assert x_transform.is_separable()
- assert y_transform.is_separable()
- BlendedTransform.__init__(self, x_transform, y_transform)
- 
- Affine2DBase.__init__(self)
- self._mtx = None
-
- def __repr__(self):
- return "BlendedAffine2D(%s,%s)" % (self._x, self._y)
- __str__ = __repr__
- 
- def _do_invalidation(self):
- if self._mtx is not None:
- self._mtx = None
- Affine2DBase._do_invalidation(self)
- return False
- return True
-
- def is_separable(self):
- return True
-
- def get_matrix(self):
- if self._mtx is None:
- if self._x == self._y:
- self._mtx = self._x.get_matrix()
- else:
- x_mtx = self._x.get_matrix()
- y_mtx = self._y.get_matrix()
- # This works because we already know the transforms are
- # separable, though normally one would want to set b and
- # c to zero.
- self._mtx = npy.vstack((x_mtx[0], y_mtx[1], [0.0, 0.0, 1.0]))
- return self._mtx
- 
-class CompositeTransform(Transform):
- def __init__(self, a, b):
- assert a.output_dims == b.input_dims
- self.input_dims = a.input_dims
- self.output_dims = b.output_dims
- 
- Transform.__init__(self)
- self._a = a
- self._b = b
- self.set_children(['_a', '_b'])
- 
- def __call__(self, points):
- return self._b(self._a(points))
- 
-class CompositeAffine2D(Affine2DBase):
- def __init__(self, a, b):
- assert a.is_affine()
- assert b.is_affine()
-
- Affine2DBase.__init__(self)
- self._a = a
- self._b = b
- self.set_children(['_a', '_b'])
- self._mtx = None
-
- def __repr__(self):
- return "CompositeAffine2D(%s, %s)" % (self._a, self._b)
- __str__ = __repr__
-
- def _do_invalidation(self):
- self._mtx = None
- Affine2DBase._do_invalidation(self)
- 
- def get_matrix(self):
- if self._mtx is None:
- self._mtx = self._concat(
- self._a.get_matrix(),
- self._b.get_matrix())
- return self._mtx
-
-class BboxTransform(Affine2DBase):
- def __init__(self, boxin, boxout):
- assert isinstance(boxin, BboxBase)
- assert isinstance(boxout, BboxBase)
-
- Affine2DBase.__init__(self)
- self._boxin = boxin
- self._boxout = boxout
- self.set_children(['_boxin', '_boxout'])
- self._mtx = None
- self._inverted = None
-
- def __repr__(self):
- return "BboxTransform(%s, %s)" % (self._boxin, self._boxout)
- __str__ = __repr__
- 
- def _do_invalidation(self):
- if self._mtx is not None:
- self._mtx = None
- Affine2DBase._do_invalidation(self)
- return False
- return True
-
- def is_separable(self):
- return True
-
- def get_matrix(self):
- if self._mtx is None:
- boxin = self._boxin
- boxout = self._boxout
- x_scale = boxout.width / boxin.width
- y_scale = boxout.height / boxin.height
-
- # MGDTODO: Optimize
- affine = Affine2D() \
- .translate(-boxin.xmin, -boxin.ymin) \
- .scale(x_scale, y_scale) \
- .translate(boxout.xmin, boxout.ymin)
-
- self._mtx = affine._mtx
- return self._mtx
-
-def blend_xy_sep_transform(x_transform, y_transform):
- if x_transform.is_affine() and y_transform.is_affine():
- return BlendedAffine2D(x_transform, y_transform)
- return BlendedTransform(x_transform, y_transform)
-
-def composite_transform_factory(a, b):
- if a.is_affine() and b.is_affine():
- return CompositeAffine2D(a, b)
- return CompositeTransform(a, b)
-
-# MGDTODO: There's probably a better place for this
-def nonsingular(vmin, vmax, expander=0.001, tiny=1e-15, increasing=True):
- '''
- Ensure the endpoints of a range are not too close together.
-
- "too close" means the interval is smaller than 'tiny' times
- the maximum absolute value.
-
- If they are too close, each will be moved by the 'expander'.
- If 'increasing' is True and vmin > vmax, they will be swapped,
- regardless of whether they are too close.
- '''
- swapped = False
- if vmax < vmin:
- vmin, vmax = vmax, vmin
- swapped = True
- if vmax - vmin <= max(abs(vmin), abs(vmax)) * tiny:
- if vmin == 0.0:
- vmin = -expander
- vmax = expander
- else:
- vmin -= expander*abs(vmin)
- vmax += expander*abs(vmax)
- if swapped and not increasing:
- vmin, vmax = vmax, vmin
- return vmin, vmax
-
-# MGDTODO: Optimize
-def interval_contains(interval, val):
- return interval[0] <= val and interval[1] >= val
-
-def interval_contains_open(interval, val):
- return interval[0] < val and interval[1] > val
- 
-if __name__ == '__main__':
- import copy
- from random import random
- import timeit
-
- bbox = Bbox.from_lbrt(10., 15., 20., 25.)
- assert bbox.xmin == 10
- assert bbox.ymin == 15
- assert bbox.xmax == 20
- assert bbox.ymax == 25
-
- assert npy.all(bbox.min == [10, 15])
- assert npy.all(bbox.max == [20, 25])
- assert npy.all(bbox.intervalx == (10, 20))
- assert npy.all(bbox.intervaly == (15, 25))
-
- assert bbox.width == 10
- assert bbox.height == 10
-
- assert bbox.bounds == (10, 15, 10, 10)
-
- print npy.asarray(bbox)
- 
- bbox.intervalx = (11, 21)
- bbox.intervaly = (16, 26)
- 
- assert bbox.bounds == (11, 16, 10, 10)
-
- bbox.xmin = 12
- bbox.ymin = 17
- bbox.xmax = 22
- bbox.ymax = 27
-
- assert bbox.bounds == (12, 17, 10, 10)
-
- bbox = Bbox.from_lbwh(10, 11, 12, 13)
- assert bbox.bounds == (10, 11, 12, 13)
-
- bbox_copy = copy.copy(bbox)
- assert bbox == bbox_copy
- bbox_copy.max = (14, 15)
- assert bbox.bounds == (10, 11, 12, 13)
- assert bbox_copy.bounds == (10, 11, 4, 4)
- 
- bbox1 = Bbox([[10., 15.], [20., 25.]])
- bbox2 = Bbox([[30., 35.], [40., 45.]])
- trans = BboxTransform(bbox1, bbox2)
- bbox3 = bbox1.transformed(trans)
- assert bbox3 == bbox2
-
- translation = Affine2D().translate(10, 20)
- assert translation.to_values() == (1, 0, 0, 1, 10, 20)
- scale = Affine2D().scale(10, 20)
- assert scale.to_values() == (10, 0, 0, 20, 0, 0)
- rotation = Affine2D().rotate_deg(30)
- print rotation.to_values() == (0.86602540378443871, 0.49999999999999994,
- -0.49999999999999994, 0.86602540378443871,
- 0.0, 0.0)
- 
- points = npy.array([[1,2],[3,4],[5,6],[7,8]], npy.float_)
- translated_points = translation(points)
- assert (translated_points == [[11., 22.], [13., 24.], [15., 26.], [17., 28.]]).all()
- scaled_points = scale(points)
- print scaled_points
- rotated_points = rotation(points)
- print rotated_points
-
- tpoints1 = rotation(translation(scale(points)))
- trans_sum = scale + translation + rotation
- tpoints2 = trans_sum(points)
- print tpoints1, tpoints2
- print tpoints1 == tpoints2
- # Need to do some sort of fuzzy comparison here?
- # assert (tpoints1 == tpoints2).all()
-
- # Here are some timing tests
- points = npy.asarray([(random(), random()) for i in xrange(10000)])
- t = timeit.Timer("trans_sum(points)", "from __main__ import trans_sum, points")
- print "Time to transform 10000 x 10 points:", t.timeit(10)
- 
-__all__ = ['Transform', 'Affine2D']
Modified: branches/transforms/lib/matplotlib/artist.py
===================================================================
--- branches/transforms/lib/matplotlib/artist.py	2007年09月14日 12:24:20 UTC (rev 3850)
+++ branches/transforms/lib/matplotlib/artist.py	2007年09月14日 13:03:31 UTC (rev 3851)
@@ -1,7 +1,7 @@
 from __future__ import division
 import sys, re
 from cbook import iterable, flatten
-from affine import Affine2D
+from transforms import Affine2D
 import matplotlib.units as units
 
 ## Note, matplotlib artists use the doc strings for set and get
Modified: branches/transforms/lib/matplotlib/axes.py
===================================================================
--- branches/transforms/lib/matplotlib/axes.py	2007年09月14日 12:24:20 UTC (rev 3850)
+++ branches/transforms/lib/matplotlib/axes.py	2007年09月14日 13:03:31 UTC (rev 3851)
@@ -9,7 +9,6 @@
 rcParams = matplotlib.rcParams
 
 from matplotlib import artist as martist
-from matplotlib import affine as maffine
 from matplotlib import agg
 from matplotlib import axis as maxis
 from matplotlib import cbook
@@ -29,6 +28,7 @@
 from matplotlib import table as mtable
 from matplotlib import text as mtext
 from matplotlib import ticker as mticker
+from matplotlib import transforms as mtransforms
 
 iterable = cbook.iterable
 is_string_like = cbook.is_string_like
@@ -481,7 +481,7 @@
 
 """
 martist.Artist.__init__(self)
- self._position = maffine.Bbox.from_lbwh(*rect)
+ self._position = mtransforms.Bbox.from_lbwh(*rect)
 self._originalPosition = copy.deepcopy(self._position)
 self.set_axes(self)
 self.set_aspect('auto')
@@ -612,7 +612,7 @@
 """
 martist.Artist.set_figure(self, fig)
 
- self.bbox = maffine.TransformedBbox(self._position, fig.transFigure)
+ self.bbox = mtransforms.TransformedBbox(self._position, fig.transFigure)
 #these will be updated later as data is added
 self._set_lim_and_transforms()
 
@@ -631,7 +631,7 @@
 set the dataLim and viewLim BBox attributes and the
 transData and transAxes Transformation attributes
 """
-	Bbox = maffine.Bbox
+	Bbox = mtransforms.Bbox
 	self.viewLim = Bbox.unit()
 	
 if self._sharex is not None:
@@ -647,20 +647,11 @@
 
 	self.dataLim = Bbox.unit()
 	
- self.transAxes = maffine.BboxTransform(
+ self.transAxes = mtransforms.BboxTransform(
 Bbox.unit(), self.bbox)
 
- localTransData = maffine.BboxTransform(
+ self.transData = mtransforms.BboxTransform(
 self.viewLim, self.bbox)
-	if self._sharex:
-	 transDataX = self._sharex.transData
-	else:
-	 transDataX = localTransData
-	if self._sharey:
-	 transDataY = self._sharey.transData
-	else:
-	 transDataY = localTransData
-	self.transData = localTransData # maffine.blend_xy_sep_transform(transDataX, transDataY)
 	 
 	 
 def get_position(self, original=False):
@@ -1538,7 +1529,7 @@
 # and min(xmin, xmax)<=0):
 # raise ValueError('Cannot set nonpositive limits with log transform')
 
- xmin, xmax = maffine.nonsingular(xmin, xmax, increasing=False)
+ xmin, xmax = mtransforms.nonsingular(xmin, xmax, increasing=False)
 
 	self.viewLim.intervalx = (xmin, xmax)
 if emit:
@@ -1670,7 +1661,7 @@
 # and min(ymin, ymax)<=0):
 # raise ValueError('Cannot set nonpositive limits with log transform')
 
- ymin, ymax = maffine.nonsingular(ymin, ymax, increasing=False)
+ ymin, ymax = mtransforms.nonsingular(ymin, ymax, increasing=False)
 	self.viewLim.intervaly = (ymin, ymax)
 if emit:
 	 self.callbacks.process('ylim_changed', self)
@@ -2167,7 +2158,7 @@
 %(Annotation)s
 """
 a = mtext.Annotation(*args, **kwargs)
- a.set_transform(maffine.Affine2D())
+ a.set_transform(mtransforms.Affine2D())
 self._set_artist_props(a)
 if kwargs.has_key('clip_on'): a.set_clip_box(self.bbox)
 self.texts.append(a)
@@ -2206,7 +2197,7 @@
 %(Line2D)s
 """
 
- trans = maffine.blend_xy_sep_transform(self.transAxes, self.transData)
+ trans = mtransforms.blend_xy_sep_transform(self.transAxes, self.transData)
 l, = self.plot([xmin,xmax], [y,y], transform=trans, scalex=False, **kwargs)
 return l
 
@@ -2242,7 +2233,7 @@
 %(Line2D)s
 """
 
- trans = maffine.blend_xy_sep_transform( self.transData, self.transAxes )
+ trans = mtransforms.blend_xy_sep_transform( self.transData, self.transAxes )
 l, = self.plot([x,x], [ymin,ymax] , transform=trans, scaley=False, **kwargs)
 return l
 
@@ -2281,7 +2272,7 @@
 %(Polygon)s
 """
 # convert y axis units
- trans = maffine.blend_xy_sep_transform( self.transAxes, self.transData)
+ trans = mtransforms.blend_xy_sep_transform( self.transAxes, self.transData)
 verts = (xmin, ymin), (xmin, ymax), (xmax, ymax), (xmax, ymin)
 p = mpatches.Polygon(verts, **kwargs)
 p.set_transform(trans)
@@ -2321,7 +2312,7 @@
 %(Polygon)s
 """
 # convert x axis units
- trans = maffine.blend_xy_sep_transform(self.transData, self.transAxes)
+ trans = mtransforms.blend_xy_sep_transform(self.transData, self.transAxes)
 verts = [(xmin, ymin), (xmin, ymax), (xmax, ymax), (xmax, ymin)]
 p = mpatches.Polygon(verts, **kwargs)
 p.set_transform(trans)
@@ -4104,7 +4095,7 @@
 offsets = zip(x,y),
 transOffset = self.transData,
 )
- collection.set_transform(maffine.Affine2D())
+ collection.set_transform(mtransforms.Affine2D())
 collection.set_alpha(alpha)
 collection.update(kwargs)
 
Modified: branches/transforms/lib/matplotlib/axis.py
===================================================================
--- branches/transforms/lib/matplotlib/axis.py	2007年09月14日 12:24:20 UTC (rev 3850)
+++ branches/transforms/lib/matplotlib/axis.py	2007年09月14日 13:03:31 UTC (rev 3851)
@@ -15,10 +15,10 @@
 from ticker import NullFormatter, FixedFormatter, ScalarFormatter, LogFormatter
 from ticker import NullLocator, FixedLocator, LinearLocator, LogLocator, AutoLocator
 
-from affine import Affine2D, Bbox, blend_xy_sep_transform, interval_contains, \
- interval_contains_open
 from font_manager import FontProperties
 from text import Text, TextWithDash, _process_text_args
+from transforms import Affine2D, Bbox, blended_transform_factory, interval_contains, \
+ interval_contains_open
 from patches import bbox_artist
 
 import matplotlib.units as units
@@ -236,7 +236,7 @@
 xaxis=True,
 )
 
-	trans = blend_xy_sep_transform(
+	trans = blended_transform_factory(
 	 self.axes.transData, self.axes.transAxes)
 #offset the text downward with a post transformation
 	trans = trans + Affine2D().translate(0, -1 * self._padPixels)
@@ -261,7 +261,7 @@
 horizontalalignment='center',
 )
 
-	trans = blend_xy_sep_transform(
+	trans = blended_transform_factory(
 	 self.axes.transData, self.axes.transAxes)
 # offset the text upward with a post transformation
 trans = trans + Affine2D().translate(0, self._padPixels)
@@ -279,7 +279,7 @@
 marker = self._xtickmarkers[0],
 markersize=self._size,
 )
- l.set_transform(blend_xy_sep_transform(
+ l.set_transform(blended_transform_factory(
 		self.axes.transData, self.axes.transAxes) )
 self._set_artist_props(l)
 return l
@@ -295,7 +295,7 @@
 markersize=self._size,
 )
 
- l.set_transform(blend_xy_sep_transform(
+ l.set_transform(blended_transform_factory(
 		self.axes.transData, self.axes.transAxes) )
 self._set_artist_props(l)
 return l
@@ -310,7 +310,7 @@
 antialiased=False,
 )
 l.set_transform(
-	 blend_xy_sep_transform(
+	 blended_transform_factory(
 		self.axes.transData, self.axes.transAxes))
 l.set_clip_box(self.axes.bbox)
 self._set_artist_props(l)
@@ -359,7 +359,7 @@
 dashdirection=0,
 xaxis=False,
 )
- trans = blend_xy_sep_transform(
+ trans = blended_transform_factory(
 	 self.axes.transAxes, self.axes.transData)
 # offset the text leftward with a post transformation
 	trans = trans + Affine2D().translate(-1 * self._padPixels, 0)
@@ -382,7 +382,7 @@
 xaxis=False,
 horizontalalignment='left',
 )
- trans = blend_xy_sep_transform(
+ trans = blended_transform_factory(
 	 self.axes.transAxes, self.axes.transData)
 # offset the text rightward with a post transformation
 	trans = trans + Affine2D().translate(self._padPixels, 0)
@@ -401,7 +401,7 @@
 markersize=self._size,
 )
 l.set_transform(
-	 blend_xy_sep_transform(
+	 blended_transform_factory(
 		self.axes.transAxes, self.axes.transData))
 self._set_artist_props(l)
 return l
@@ -417,7 +417,7 @@
 )
 
 l.set_transform(
-	 blend_xy_sep_transform(
+	 blended_transform_factory(
 		self.axes.transAxes, self.axes.transData))
 self._set_artist_props(l)
 return l
@@ -432,7 +432,7 @@
 antialiased=False,
 )
 
- l.set_transform( blend_xy_sep_transform(
+ l.set_transform( blended_transform_factory(
 		self.axes.transAxes, self.axes.transData) )
 l.set_clip_box(self.axes.bbox)
 
@@ -979,7 +979,7 @@
 verticalalignment='top',
 horizontalalignment='center',
 )
- label.set_transform( blend_xy_sep_transform(
+ label.set_transform( blended_transform_factory(
 		self.axes.transAxes, Affine2D() ))
 
 self._set_artist_props(label)
@@ -994,7 +994,7 @@
 verticalalignment='top',
 horizontalalignment='right',
 )
- offsetText.set_transform( blend_xy_sep_transform(
+ offsetText.set_transform( blended_transform_factory(
 		self.axes.transAxes, Affine2D() ))
 self._set_artist_props(offsetText)
 self.offset_text_position='bottom'
@@ -1169,7 +1169,7 @@
 horizontalalignment='right',
 rotation='vertical',
 )
- label.set_transform( blend_xy_sep_transform(
+ label.set_transform( blended_transform_factory(
 		Affine2D(), self.axes.transAxes) )
 
 self._set_artist_props(label)
@@ -1184,7 +1184,7 @@
 verticalalignment = 'bottom',
 horizontalalignment = 'left',
 )
- offsetText.set_transform(blend_xy_sep_transform(
+ offsetText.set_transform(blended_transform_factory(
 		self.axes.transAxes, Affine2D()) )
 self._set_artist_props(offsetText)
 self.offset_text_position='left'
Modified: branches/transforms/lib/matplotlib/backends/backend_agg.py
===================================================================
--- branches/transforms/lib/matplotlib/backends/backend_agg.py	2007年09月14日 12:24:20 UTC (rev 3850)
+++ branches/transforms/lib/matplotlib/backends/backend_agg.py	2007年09月14日 13:03:31 UTC (rev 3851)
@@ -84,7 +84,7 @@
 from matplotlib.font_manager import findfont
 from matplotlib.ft2font import FT2Font, LOAD_DEFAULT
 from matplotlib.mathtext import MathTextParser
-from matplotlib.affine import Bbox
+from matplotlib.transforms import Bbox
 
 from _backend_agg import RendererAgg as _RendererAgg
 
@@ -115,15 +115,10 @@
 'debug-annoying')
 # self.draw_polygon = self._renderer.draw_polygon
 self.draw_rectangle = self._renderer.draw_rectangle
- self.draw_path = self._renderer.draw_path
 	# MGDTODO -- remove these lines
 # self.draw_lines = self._renderer.draw_lines
 # self.draw_markers = self._renderer.draw_markers
 self.draw_image = self._renderer.draw_image
- self.draw_line_collection = self._renderer.draw_line_collection
- self.draw_quad_mesh = self._renderer.draw_quad_mesh
- self.draw_poly_collection = self._renderer.draw_poly_collection
- self.draw_regpoly_collection = self._renderer.draw_regpoly_collection
 
 self.copy_from_bbox = self._renderer.copy_from_bbox
 self.restore_region = self._renderer.restore_region
Modified: branches/transforms/lib/matplotlib/figure.py
===================================================================
--- branches/transforms/lib/matplotlib/figure.py	2007年09月14日 12:24:20 UTC (rev 3850)
+++ branches/transforms/lib/matplotlib/figure.py	2007年09月14日 13:03:31 UTC (rev 3851)
@@ -18,8 +18,8 @@
 from text import Text, _process_text_args
 
 from legend import Legend
-from affine import Affine2D, Bbox, BboxTransform, TransformedBbox
 from ticker import FormatStrFormatter
+from transforms import Affine2D, Bbox, BboxTransform, TransformedBbox
 from cm import ScalarMappable
 from contour import ContourSet
 import warnings
Modified: branches/transforms/lib/matplotlib/finance.py
===================================================================
--- branches/transforms/lib/matplotlib/finance.py	2007年09月14日 12:24:20 UTC (rev 3850)
+++ branches/transforms/lib/matplotlib/finance.py	2007年09月14日 13:03:31 UTC (rev 3851)
@@ -22,7 +22,7 @@
 from matplotlib.colors import colorConverter
 from lines import Line2D, TICKLEFT, TICKRIGHT
 from patches import Rectangle
-from matplotlib.affine import Affine2D
+from matplotlib.transforms import Affine2D
 
 
 
Modified: branches/transforms/lib/matplotlib/legend.py
===================================================================
--- branches/transforms/lib/matplotlib/legend.py	2007年09月14日 12:24:20 UTC (rev 3850)
+++ branches/transforms/lib/matplotlib/legend.py	2007年09月14日 13:03:31 UTC (rev 3851)
@@ -34,7 +34,7 @@
 from patches import Patch, Rectangle, RegularPolygon, Shadow, bbox_artist, draw_bbox
 from collections import LineCollection, RegularPolyCollection, PatchCollection
 from text import Text
-from affine import Bbox, BboxTransform
+from transforms import Bbox, BboxTransform
 
 def line_cuts_bbox(line, bbox):
 """ Return True if and only if line cuts bbox. """
Modified: branches/transforms/lib/matplotlib/lines.py
===================================================================
--- branches/transforms/lib/matplotlib/lines.py	2007年09月14日 12:24:20 UTC (rev 3850)
+++ branches/transforms/lib/matplotlib/lines.py	2007年09月14日 13:03:31 UTC (rev 3851)
@@ -14,10 +14,10 @@
 import numerix.ma as ma
 from matplotlib import verbose
 import artist
-from affine import Bbox
 from artist import Artist, setp
 from cbook import iterable, is_string_like, is_numlike
 from colors import colorConverter
+from transforms import Bbox
 
 from matplotlib import rcParams
 
Modified: branches/transforms/lib/matplotlib/table.py
===================================================================
--- branches/transforms/lib/matplotlib/table.py	2007年09月14日 12:24:20 UTC (rev 3850)
+++ branches/transforms/lib/matplotlib/table.py	2007年09月14日 13:03:31 UTC (rev 3851)
@@ -29,7 +29,7 @@
 from patches import Rectangle
 from cbook import enumerate, is_string_like, flatten
 from text import Text
-from affine import Bbox
+from transforms import Bbox
 
 
 
Modified: branches/transforms/lib/matplotlib/text.py
===================================================================
--- branches/transforms/lib/matplotlib/text.py	2007年09月14日 12:24:20 UTC (rev 3850)
+++ branches/transforms/lib/matplotlib/text.py	2007年09月14日 13:03:31 UTC (rev 3851)
@@ -15,7 +15,7 @@
 from cbook import enumerate, is_string_like, maxdict, is_numlike
 from font_manager import FontProperties
 from patches import bbox_artist, YAArrow
-from affine import Affine2D, Bbox
+from transforms import Affine2D, Bbox
 from lines import Line2D
 
 import matplotlib.nxutils as nxutils
Modified: branches/transforms/lib/matplotlib/ticker.py
===================================================================
--- branches/transforms/lib/matplotlib/ticker.py	2007年09月14日 12:24:20 UTC (rev 3850)
+++ branches/transforms/lib/matplotlib/ticker.py	2007年09月14日 13:03:31 UTC (rev 3851)
@@ -109,7 +109,7 @@
 import matplotlib as mpl
 from matplotlib import verbose, rcParams
 from matplotlib import cbook
-from matplotlib import affine as maffine
+from matplotlib import transforms as mtransforms
 
 
 
@@ -540,7 +540,7 @@
 def autoscale(self):
 'autoscale the view limits'
 self.verify_intervals()
- return maffine.nonsingular(*self.dataInterval.get_bounds())
+ return mtransforms.nonsingular(*self.dataInterval.get_bounds())
 
 def pan(self, numsteps):
 'Pan numticks (can be positive or negative)'
@@ -682,7 +682,7 @@
 vmin = math.floor(scale*vmin)/scale
 vmax = math.ceil(scale*vmax)/scale
 
- return maffine.nonsingular(vmin, vmax)
+ return mtransforms.nonsingular(vmin, vmax)
 
 
 def closeto(x,y):
@@ -766,7 +766,7 @@
 vmin -=1
 vmax +=1
 
- return maffine.nonsingular(vmin, vmax)
+ return mtransforms.nonsingular(vmin, vmax)
 
 def scale_range(vmin, vmax, n = 1, threshold=100):
 dv = abs(vmax - vmin)
@@ -833,12 +833,12 @@
 
 def __call__(self):
 vmin, vmax = self.axis.get_view_interval()
- vmin, vmax = maffine.nonsingular(vmin, vmax, expander = 0.05)
+ vmin, vmax = mtransforms.nonsingular(vmin, vmax, expander = 0.05)
 return self.bin_boundaries(vmin, vmax)
 
 def autoscale(self):
 dmin, dmax = self.axis.get_data_interval()
- dmin, dmax = maffine.nonsingular(dmin, dmax, expander = 0.05)
+ dmin, dmax = mtransforms.nonsingular(dmin, dmax, expander = 0.05)
 return npy.take(self.bin_boundaries(dmin, dmax), [0,-1])
 
 
@@ -939,7 +939,7 @@
 if vmin==vmax:
 vmin = decade_down(vmin,self._base)
 vmax = decade_up(vmax,self._base)
- return maffine.nonsingular(vmin, vmax)
+ return mtransforms.nonsingular(vmin, vmax)
 
 class AutoLocator(MaxNLocator):
 def __init__(self):
Copied: branches/transforms/lib/matplotlib/transforms.py (from rev 3849, branches/transforms/lib/matplotlib/affine.py)
===================================================================
--- branches/transforms/lib/matplotlib/transforms.py	 (rev 0)
+++ branches/transforms/lib/matplotlib/transforms.py	2007年09月14日 13:03:31 UTC (rev 3851)
@@ -0,0 +1,852 @@
+"""
+A set of classes to handle transformations.
+
+2007 Michael Droettboom
+"""
+
+import numpy as npy
+from numpy.linalg import inv
+from sets import Set
+
+# MGDTODO: This creates a ton of cyclical references. We may want to
+# consider using weak references
+
+# MGDTODO: deep copying is probably incorrect wrt the parent/child
+# relationships
+
+class TransformNode(object):
+ def __init__(self):
+ self._parents = Set()
+ 
+ def invalidate(self):
+ if not self._do_invalidation():
+ for parent in self._parents:
+ parent.invalidate()
+
+ def _do_invalidation(self):
+ return False
+
+ def set_children(self, children):
+ for child in children:
+ getattr(self, child)._parents.add(self)
+ self._children = children
+
+ # MGDTODO: decide whether we need this in-place updating and
+ # remove if not
+# def replace_child(self, index, child):
+# children = self._children
+# getattr(self, children[index])._parents.remove(self)
+# setattr(self, children[index], child)
+# # We have to reset children in case two or more
+# # of the children are the same
+# for child in children:
+# getattr(self, child)._parents.add(self)
+# self.invalidate()
+ 
+class BboxBase(TransformNode):
+ '''
+ This is the read-only part of a bounding-box
+ '''
+ 
+ def __init__(self):
+ TransformNode.__init__(self)
+ 
+ def __array__(self):
+ return self.get_points()
+ 
+ # MGDTODO: Probably a more efficient ways to do this...
+ def _get_xmin(self):
+ return self.get_points()[0, 0]
+ xmin = property(_get_xmin)
+ 
+ def _get_ymin(self):
+ return self.get_points()[0, 1]
+ ymin = property(_get_ymin)
+
+ def _get_xmax(self):
+ return self.get_points()[1, 0]
+ xmax = property(_get_xmax)
+
+ def _get_ymax(self):
+ return self.get_points()[1, 1]
+ ymax = property(_get_ymax)
+
+ def _get_min(self):
+ return self.get_points()[0]
+ min = property(_get_min)
+ 
+ def _get_max(self):
+ return self.get_points()[1]
+ max = property(_get_max)
+ 
+ def _get_intervalx(self):
+ return self.get_points()[:, 0]
+ intervalx = property(_get_intervalx)
+
+ def _get_intervaly(self):
+ return self.get_points()[:, 1]
+ intervaly = property(_get_intervaly)
+ 
+ def _get_width(self):
+ return self.xmax - self.xmin
+ width = property(_get_width)
+
+ def _get_height(self):
+ return self.ymax - self.ymin
+ height = property(_get_height)
+
+ def _get_bounds(self):
+ return (self.xmin, self.ymin,
+ self.xmax - self.xmin, self.ymax - self.ymin)
+ bounds = property(_get_bounds)
+
+ def get_points(self):
+ return NotImplementedError()
+
+ # MGDTODO: Optimize
+ def containsx(self, x):
+ return x >= self.xmin and x <= self.xmax
+
+ def containsy(self, y):
+ return y >= self.ymin and y <= self.ymax
+ 
+ def contains(self, x, y):
+ return self.containsx(x) and self.containsy(y)
+
+ def overlapsx(self, other):
+ return self.containsx(other.xmin) \
+ or self.containsx(other.xmax)
+
+ def overlapsy(self, other):
+ return self.containsy(other.ymin) \
+ or self.containsx(other.ymax)
+ 
+ def overlaps(self, other):
+ return self.overlapsx(other) \
+ and self.overlapsy(other)
+ 
+ def fully_containsx(self, x):
+ return x > self.xmin and x < self.xmax
+
+ def fully_containsy(self, y):
+ return y > self.ymin and y < self.ymax
+ 
+ def fully_contains(self, x, y):
+ return self.fully_containsx(x) \
+ and self.fully_containsy(y)
+
+ def fully_overlapsx(self, other):
+ return self.fully_containsx(other.xmin) \
+ or self.fully_containsx(other.xmax)
+
+ def fully_overlapsy(self, other):
+ return self.fully_containsy(other.ymin) \
+ or self.fully_containsx(other.ymax)
+ 
+ def fully_overlaps(self, other):
+ return self.fully_overlapsx(other) and \
+ self.fully_overlapsy(other)
+
+ 
+class Bbox(BboxBase):
+ def __init__(self, points):
+ BboxBase.__init__(self)
+ self._points = npy.asarray(points, npy.float_)
+
+ #@staticmethod
+ def unit():
+ return Bbox.from_lbrt(0., 0., 1., 1.)
+ unit = staticmethod(unit)
+
+ #@staticmethod
+ def from_lbwh(left, bottom, width, height):
+ return Bbox.from_lbrt(left, bottom, left + width, bottom + height)
+ from_lbwh = staticmethod(from_lbwh)
+
+ #@staticmethod
+ def from_lbrt(*args):
+ points = npy.array(args, dtype=npy.float_).reshape(2, 2)
+ return Bbox(points)
+ from_lbrt = staticmethod(from_lbrt)
+ 
+ def __copy__(self):
+ return Bbox(self._points.copy())
+
+ def __deepcopy__(self, memo):
+ return Bbox(self._points.copy())
+ 
+ def __cmp__(self, other):
+ # MGDTODO: Totally suboptimal
+ if isinstance(other, Bbox) and (self._points == other._points).all():
+ return 0
+ return -1
+
+ def __repr__(self):
+ return 'Bbox(%s)' % repr(self._points)
+ __str__ = __repr__
+
+ # JDH: the update method will update the box limits from the
+ # existing limits and the new data; it appears here you are just
+ # using the new data. We use an "ignore" flag to specify whether
+ # you want to include the existing data or not in the update
+ def update_from_data(self, x, y, ignore=True):
+ self._points = npy.array(
+ [[x.min(), y.min()], [x.max(), y.max()]],
+ npy.float_)
+ self.invalidate()
+
+ # MGDTODO: Probably a more efficient ways to do this...
+ def _set_xmin(self, val):
+ self._points[0, 0] = val
+ self.invalidate()
+ xmin = property(BboxBase._get_xmin, _set_xmin)
+
+ def _set_ymin(self, val):
+ self._points[0, 1] = val
+ self.invalidate()
+ ymin = property(BboxBase._get_ymin, _set_ymin)
+
+ def _set_xmax(self, val):
+ self._points[1, 0] = val
+ self.invalidate()
+ xmax = property(BboxBase._get_xmax, _set_xmax)
+
+ def _set_ymax(self, val):
+ self._points[1, 1] = val
+ self.invalidate()
+ ymax = property(BboxBase._get_ymax, _set_ymax)
+
+ def _set_min(self, val):
+ self._points[0] = val
+ self.invalidate()
+ min = property(BboxBase._get_min, _set_min)
+ 
+ def _set_max(self, val):
+ self._points[1] = val
+ self.invalidate()
+ max = property(BboxBase._get_max, _set_max)
+ 
+ def _set_intervalx(self, interval):
+ self._points[:, 0] = interval
+ self.invalidate()
+ intervalx = property(BboxBase._get_intervalx, _set_intervalx)
+
+ def _set_intervaly(self, interval):
+ self._points[:, 1] = interval
+ self.invalidate()
+ intervaly = property(BboxBase._get_intervaly, _set_intervaly)
+
+ def _set_bounds(self, bounds):
+ l,b,w,h = bounds
+ self._points = npy.array([[l, b], [l+w, b+h]], npy.float_)
+ self.invalidate()
+ bounds = property(BboxBase._get_bounds, _set_bounds)
+
+ def get_points(self):
+ return self._points
+
+ def set_points(self, points):
+ self._points = points
+ self.invalidate()
+
+ def set(self, other):
+ self._points = other.get_points()
+ self.invalidate()
+ 
+ def transformed(self, transform):
+ return Bbox(transform(self._points))
+
+ def inverse_transformed(self, transform):
+ return Bbox(transform.inverted()(self._points))
+ 
+ def expanded(self, sw, sh):
+ width = self.width
+ height = self.height
+ deltaw = (sw * width - width) / 2.0
+ deltah = (sh * height - height) / 2.0
+ a = npy.array([[-deltaw, -deltah], [deltaw, deltah]])
+ return Bbox(self._points + a)
+
+ #@staticmethod
+ def union(bboxes):
+ """
+ Return the Bbox that bounds all bboxes
+ """
+ assert(len(bboxes))
+
+ if len(bboxes) == 1:
+ return bboxes[0]
+
+ bbox = bboxes[0]
+ xmin = bbox.xmin
+ ymin = bbox.ymin
+ xmax = bbox.xmax
+ ymax = bbox.ymax
+
+ for bbox in bboxes[1:]:
+ xmin = min(xmin, bbox.xmin)
+ ymin = min(ymin, bbox.ymin)
+ xmax = max(xmax, bbox.xmax)
+ ymax = max(ymax, bbox.ymax)
+
+ return Bbox.from_lbrt(xmin, ymin, xmax, ymax)
+ union = staticmethod(union)
+
+class TransformedBbox(BboxBase):
+ def __init__(self, bbox, transform):
+ assert isinstance(bbox, Bbox)
+ assert isinstance(transform, Transform)
+
+ BboxBase.__init__(self)
+ self.bbox = bbox
+ self.transform = transform
+ self.set_children(['bbox', 'transform'])
+ self._points = None
+
+ def __repr__(self):
+ return "TransformedBbox(%s, %s)" % (self.bbox, self.transform)
+ __str__ = __repr__
+ 
+ def _do_invalidation(self):
+ self._points = None
+
+ def get_points(self):
+ if self._points is None:
+ self._points = self.transform(self.bbox.get_points())
+ return self._points
+
+# MGDTODO: This code probably works, but I don't think it's a good idea
+# (from a code clarity perspective)
+# class BlendedBbox(BboxBase):
+# def __init__(self, bbox_x, bbox_y):
+# assert isinstance(bbox_x, BboxBase)
+# assert isinstance(bbox_y, BboxBase)
+
+# BboxBase.__init__(self)
+# self._x = bbox_x
+# self._y = bbox_y
+# self.set_children(['_x', '_y'])
+# self._points = None
+
+# def __repr__(self):
+# return "TransformedBbox(%s, %s)" % (self.bbox, self.transform)
+# __str__ = __repr__
+ 
+# def _do_invalidation(self):
+# self._points = None
+
+# def get_points(self):
+# if self._points is None:
+# # MGDTODO: Optimize
+# if self._x == self._y:
+# self._points = self._x.get_points()
+# else:
+# x_points = self._x.get_points()
+# y_points = self._y.get_points()
+# self._points = npy.array(
+# [[x_points[0,0], y_points[0,1]],
+# [x_points[1,0], y_points[1,1]]],
+# npy.float_)
+# return self._points
+
+# def _set_intervalx(self, pair):
+# # MGDTODO: Optimize
+# bbox = Bbox([[pair[0], 0.0], [pair[1], 0.0]])
+# self.replace_child(0, bbox)
+# intervalx = property(BboxBase._get_intervalx, _set_intervalx)
+
+# def _set_intervaly(self, pair):
+# # MGDTODO: Optimize
+# bbox = Bbox([[0.0, pair[0]], [0.0, pair[1]]])
+# self.replace_child(1, bbox)
+# intervaly = property(BboxBase._get_intervaly, _set_intervaly)
+ 
+class Transform(TransformNode):
+ def __init__(self):
+ TransformNode.__init__(self)
+ 
+ def __call__(self, points):
+ raise NotImplementedError()
+
+ def __add__(self, other):
+ if isinstance(other, Transform):
+ return composite_transform_factory(self, other)
+ raise TypeError(
+ "Can not add Transform to object of type '%s'" % type(other))
+
+ def __radd__(self, other):
+ if isinstance(other, Transform):
+ return composite_transform_factory(other, self)
+ raise TypeError(
+ "Can not add Transform to object of type '%s'" % type(other))
+
+ def transform_point(self, point):
+ return self.__call__(npy.asarray([point]))[0]
+ 
+ def has_inverse(self):
+ raise NotImplementedError()
+ 
+ def inverted(self):
+ raise NotImplementedError()
+
+ def is_separable(self):
+ return False
+
+ def is_affine(self):
+ return False
+
+class Affine2DBase(Transform):
+ input_dims = 2
+ output_dims = 2
+
+ def __init__(self):
+ Transform.__init__(self)
+ self._inverted = None
+
+ def _do_invalidation(self):
+ result = self._inverted is None
+ self._inverted = None
+ return result
+
+ #@staticmethod
+ def _concat(a, b):
+ return npy.dot(b, a)
+ _concat = staticmethod(_concat)
+
+ #@staticmethod
+ def concat(a, b):
+ return Affine2D(Affine2D._concat(a.get_matrix(), b.get_matrix()))
+ concat = staticmethod(concat)
+ 
+ def to_values(self):
+ mtx = self.get_matrix()
+ return tuple(mtx[:2].swapaxes(0, 1).flatten())
+ 
+ #@staticmethod
+ def matrix_from_values(a, b, c, d, e, f):
+ affine = npy.zeros((3, 3), npy.float_)
+ affine[0, ] = a, c, e
+ affine[1, ] = b, d, f
+ affine[2, 2] = 1
+ return affine
+ matrix_from_values = staticmethod(matrix_from_values)
+
+ def get_matrix(self):
+ raise NotImplementedError()
+ 
+ def __call__(self, points):
+ """
+ Applies the transformation to an array of 2D points and
+ returns the result.
+
+ points must be a numpy array of shape (N, 2), where N is the
+ number of points.
+ """
+ # MGDTODO: The major speed trap here is just converting to
+ # the points to an array in the first place. If we can use
+ # more arrays upstream, that should help here.
+ if not isinstance(points, npy.ndarray):
+ import traceback
+ print '-' * 60
+ print 'A non-numpy array was passed in for transformation. Please '
+ print 'correct this.'
+ print "".join(traceback.format_stack())
+ print points
+ mtx = self.get_matrix()...
 
[truncated message content]
From: <md...@us...> - 2007年09月14日 18:01:00
Revision: 3852
 http://matplotlib.svn.sourceforge.net/matplotlib/?rev=3852&view=rev
Author: mdboom
Date: 2007年09月14日 10:57:52 -0700 (2007年9月14日)
Log Message:
-----------
Sends paths to backend only once, and after that uses the "native" path by
reference with a changing transform. Started recongfiguring
patches.py to use only Paths under the hood (to take advantage of this
caching). Removed many methods from backend_agg that should
eventually be replaced by draw_path, at least in theory.
Modified Paths:
--------------
 branches/transforms/lib/matplotlib/backend_bases.py
 branches/transforms/lib/matplotlib/backends/backend_agg.py
 branches/transforms/lib/matplotlib/lines.py
 branches/transforms/lib/matplotlib/patches.py
 branches/transforms/lib/matplotlib/transforms.py
 branches/transforms/src/_backend_agg.cpp
 branches/transforms/src/_backend_agg.h
Added Paths:
-----------
 branches/transforms/lib/matplotlib/path.py
Modified: branches/transforms/lib/matplotlib/backend_bases.py
===================================================================
--- branches/transforms/lib/matplotlib/backend_bases.py	2007年09月14日 13:03:31 UTC (rev 3851)
+++ branches/transforms/lib/matplotlib/backend_bases.py	2007年09月14日 17:57:52 UTC (rev 3852)
@@ -4,7 +4,7 @@
 """
 
 from __future__ import division
-import os, sys, warnings, copy
+import os, sys, warnings, copy, weakref
 
 import numpy as npy
 import matplotlib.numerix.npyma as ma
@@ -17,7 +17,10 @@
 class RendererBase:
 """An abstract base class to handle drawing/rendering operations
 """
-
+ # This will cache paths across rendering instances
+ # Each subclass of RenderBase should define this -->
+ # _paths = weakref.WeakKeyDictionary()
+ 
 def __init__(self):
 self._texmanager = None
 
@@ -33,7 +36,35 @@
 """
 pass
 
+ def draw_path(self, gc, path, transform, rgbFace = None):
+	"""
+	Handles the caching of the native path associated with the
+	given path and calls the underlying backend's _draw_path to
+	actually do the drawing.
+	"""
+	native_path = self._native_paths.get(path)
+	if native_path is None:
+	 import matplotlib.patches
+	 print "CACHE MISS", path
+	 native_path = self.convert_to_native_path(path)
+	 self._native_paths[path] = native_path
+	self._draw_path(gc, native_path, transform, rgbFace)
 
+ def _draw_path(self, gc, native_path, transform, rgbFace):
+	"""
+	Draw the native path object with the given GraphicsContext and
+	transform. The transform passed in will always be affine.
+	"""
+	raise NotImplementedError
+	
+ def convert_to_native_path(self, path):
+	"""
+	Backends will normally will override this, but if they don't need any
+	special optimizations, they can just have the generic path data
+	passed to them in draw_path.
+	"""
+	return path
+	
 def draw_arc(self, gc, rgbFace, x, y, width, height, angle1, angle2,
 rotation):
 """
@@ -75,6 +106,9 @@
 """
 return False
 
+ def draw_markers(self, gc, marker_path, marker_trans, path, trans, rgbFace=None):
+	pass
+ 
 def _draw_markers(self, bgc, path, rgbFace, x, y, trans):
 """
 This method is currently underscore hidden because the
Modified: branches/transforms/lib/matplotlib/backends/backend_agg.py
===================================================================
--- branches/transforms/lib/matplotlib/backends/backend_agg.py	2007年09月14日 13:03:31 UTC (rev 3851)
+++ branches/transforms/lib/matplotlib/backends/backend_agg.py	2007年09月14日 17:57:52 UTC (rev 3852)
@@ -69,7 +69,7 @@
 
 """
 from __future__ import division
-import os, sys
+import os, sys, weakref
 
 import numpy as npy
 
@@ -95,7 +95,15 @@
 The renderer handles all the drawing primitives using a graphics
 context instance that controls the colors/styles
 """
-
+ # MGDTODO: Renderers seem to get created and destroyed fairly
+ # often so the paths are cached at the class (not instance) level.
+ # However, this dictionary is only directly used by RendererBase,
+ # so it seems funny to define it here. However, if we didn't, the
+ # native paths would be shared across renderers, which is
+ # obviously bad. Seems like a good use of metaclasses, but that
+ # also seems like a heavy solution for a minor problem.
+ _native_paths = weakref.WeakKeyDictionary()
+ 
 debug=1
 texd = {} # a cache of tex image rasters
 def __init__(self, width, height, dpi):
@@ -129,6 +137,12 @@
 if __debug__: verbose.report('RendererAgg.__init__ done',
 'debug-annoying')
 
+ def convert_to_native_path(self, path):
+	return self._renderer.convert_to_native_path(path.vertices, path.codes)
+
+ def _draw_path(self, gc, native_path, transform, rgbFace):
+	return self._renderer.draw_path(gc, native_path, transform.to_values(), rgbFace)
+	
 def draw_arc(self, gcEdge, rgbFace, x, y, width, height, angle1, angle2, rotation):
 """
 Draw an arc centered at x,y with width and height and angles
Modified: branches/transforms/lib/matplotlib/lines.py
===================================================================
--- branches/transforms/lib/matplotlib/lines.py	2007年09月14日 13:03:31 UTC (rev 3851)
+++ branches/transforms/lib/matplotlib/lines.py	2007年09月14日 17:57:52 UTC (rev 3852)
@@ -10,14 +10,14 @@
 
 import numpy as npy
 
-import agg
 import numerix.ma as ma
 from matplotlib import verbose
 import artist
 from artist import Artist, setp
 from cbook import iterable, is_string_like, is_numlike
 from colors import colorConverter
-from transforms import Bbox
+from path import Path
+from transforms import Affine2D, Bbox
 
 from matplotlib import rcParams
 
@@ -284,9 +284,6 @@
 self.set_data(xdata, ydata)
 self._logcache = None
 
- # TODO: do we really need 'newstyle'
- self._newstyle = False
-
 def contains(self, mouseevent):
 """Test whether the mouse event occurred on the line. The pick radius determines
 the precision of the location test (usually within five points of the value). Use
@@ -427,6 +424,7 @@
 if len(x) != len(y):
 raise RuntimeError('xdata and ydata must be the same length')
 
+	# MGDTODO: Deal with segments
 mx = ma.getmask(x)
 my = ma.getmask(y)
 mask = ma.mask_or(mx, my)
@@ -439,7 +437,9 @@
 
 self._x = npy.asarray(x, float)
 self._y = npy.asarray(y, float)
-
+	self._path = Path(npy.vstack((self._x, self._y)).transpose(),
+			 closed=False)
+	
 self._logcache = None
 
 
@@ -508,30 +508,19 @@
 gc.set_joinstyle(join)
 gc.set_capstyle(cap)
 
- if self._newstyle:
- # transform in backend
- xt = self._x
- yt = self._y
- else:
- x, y = self._get_plottable()
- if len(x)==0: return
- xt, yt = self.get_transform().numerix_x_y(x, y)
-
-
-
 funcname = self._lineStyles.get(self._linestyle, '_draw_nothing')
 lineFunc = getattr(self, funcname)
 
+	# MGDTODO: Deal with self._segments
 if self._segments is not None:
 for ii in self._segments:
 lineFunc(renderer, gc, xt[ii[0]:ii[1]], yt[ii[0]:ii[1]])
 
 else:
- lineFunc(renderer, gc, xt, yt)
-
-
- if self._marker is not None:
-
+ lineFunc(renderer, gc, self._path)
+	 
+	# MGDTODO: Deal with markers
+ if self._marker is not None and False:
 gc = renderer.new_gc()
 self._set_gc_clip(gc)
 gc.set_foreground(self.get_markeredgecolor())
@@ -539,7 +528,7 @@
 gc.set_alpha(self._alpha)
 funcname = self._markers.get(self._marker, '_draw_nothing')
 markerFunc = getattr(self, funcname)
- markerFunc(renderer, gc, xt, yt)
+ markerFunc(renderer, gc, self._path)
 
 #renderer.close_group('line2d')
 
@@ -720,7 +709,7 @@
 self.set_linestyle('--')
 self._dashSeq = seq # TODO: offset ignored for now
 
- def _draw_nothing(self, renderer, gc, xt, yt):
+ def _draw_nothing(self, renderer, gc, path):
 pass
 
 def _draw_steps(self, renderer, gc, xt, yt):
@@ -737,13 +726,10 @@
 else:
 renderer.draw_lines(gc, xt2, yt2)
 
- def _draw_solid(self, renderer, gc, xt, yt):
- if len(xt)<2: return
+ def _draw_solid(self, renderer, gc, path):
+ # if len(xt)<2: return
 gc.set_linestyle('solid')
- if self._newstyle:
- renderer.draw_lines(gc, xt, yt, self.get_transform())
- else:
- renderer.draw_lines(gc, xt, yt)
+	renderer.draw_path(gc, path, self.get_transform())
 
 
 def _draw_dashed(self, renderer, gc, xt, yt):
@@ -1103,16 +1089,12 @@
 for (x,y) in zip(xt, yt):
 renderer.draw_line(gc, x, y, x+offset, y)
 
+ _tickup_path = Path([[-0.5, 0.0], [-0.5, 1.0]])
 def _draw_tickup(self, renderer, gc, xt, yt):
 offset = renderer.points_to_pixels(self._markersize)
- if self._newstyle:
- path = agg.path_storage()
- path.move_to(-0.5, 0)
- path.line_to(-0.5, offset)
- renderer.draw_markers(gc, path, None, xt, yt, self.get_transform())
- else:
- for (x,y) in zip(xt, yt):
- renderer.draw_line(gc, x, y, x, y+offset)
+	marker_transform = Affine2D().scale(1.0, offset)
+	renderer.draw_markers(gc, self._tickup_path, marker_transform,
+			 self._path, self.get_transform())
 
 def _draw_tickdown(self, renderer, gc, xt, yt):
 offset = renderer.points_to_pixels(self._markersize)
Modified: branches/transforms/lib/matplotlib/patches.py
===================================================================
--- branches/transforms/lib/matplotlib/patches.py	2007年09月14日 13:03:31 UTC (rev 3851)
+++ branches/transforms/lib/matplotlib/patches.py	2007年09月14日 17:57:52 UTC (rev 3852)
@@ -11,8 +11,8 @@
 import matplotlib.nxutils as nxutils
 import matplotlib.mlab as mlab
 import matplotlib.artist as artist
+from matplotlib.path import Path
 
-
 # these are not available for the object inspector until after the
 # class is build so we define an initial set here for the init
 # function and they will be overridden after object defn
@@ -73,7 +73,7 @@
 self._antialiased = antialiased
 self._hatch = hatch
 self.fill = fill
-
+	
 if len(kwargs): artist.setp(self, **kwargs)
 __init__.__doc__ = cbook.dedent(__init__.__doc__) % artist.kwdocd
 
@@ -84,8 +84,10 @@
 
 Returns T/F, {}
 """
- if callable(self._contains): return self._contains(self,mouseevent)
+	# MGDTODO: This will probably need to be implemented in C++
 
+	if callable(self._contains): return self._contains(self,mouseevent)
+
 try:
 # TODO: make this consistent with patch collection algorithm
 x, y = self.get_transform().inverse_xy_tup((mouseevent.x, mouseevent.y))
@@ -107,7 +109,6 @@
 self.set_figure(other.get_figure())
 self.set_alpha(other.get_alpha())
 
-
 def get_antialiased(self):
 return self._antialiased
 
@@ -210,22 +211,16 @@
 if self._hatch:
 gc.set_hatch(self._hatch )
 
- verts = self.get_verts()
- tverts = self.get_transform()(verts)
+ path = self.get_path()
+ transform = self.get_transform()
 
-	# MGDTODO: This result is an Nx2 numpy array, which could be passed
-	# directly to renderer.draw_polygon since it currently expects
-	# a list of tuples so we're converting it to that now.
-	tverts = [tuple(x) for x in tverts]
-	
- renderer.draw_polygon(gc, rgbFace, tverts)
+ renderer.draw_path(gc, path, transform, rgbFace)
 
-
 #renderer.close_group('patch')
 
- def get_verts(self):
+ def get_path(self):
 """
- Return the vertices of the patch
+ Return the path of this patch
 """
 raise NotImplementedError('Derived must override')
 
@@ -286,9 +281,10 @@
 %(Patch)s
 """
 Patch.__init__(self)
- self.ox, self.oy = ox, oy
 self.patch = patch
 self.props = props
+	self.ox, self.oy = ox, oy
+	self._shadow_transform = transforms.Affine2D.translate(self.ox, self.oy)
 self._update()
 __init__.__doc__ = cbook.dedent(__init__.__doc__) % artist.kwdocd
 
@@ -306,18 +302,13 @@
 
 self.set_facecolor((r,g,b))
 self.set_edgecolor((r,g,b))
+	 
+ def get_path(self):
+ return self.patch.get_path()
 
- def get_verts(self):
- verts = self.patch.get_verts()
- xs = self.convert_xunits([x+self.ox for x,y in verts])
- ys = self.convert_yunits([y+self.oy for x,y in verts])
- return zip(xs, ys)
-
- def _draw(self, renderer):
- 'draw the shadow'
- self._update()
- Patch.draw(self, renderer)
-
+ def get_transform(self):
+	return self._transform + self._shadow_transform
+ 
 class Rectangle(Patch):
 """
 Draw a rectangle with lower left at xy=(x,y) with specified
@@ -325,12 +316,16 @@
 
 """
 
+ _path = Path(
+	[[0.0, 0.0], [1.0, 0.0], [1.0, 1.0], [0.0, 1.0]])
+ 
 def __str__(self):
 return str(self.__class__).split('.')[-1] \
 + "(%g,%g;%gx%g)"%(self.xy[0],self.xy[1],self.width,self.height)
 
- def __init__(self, xy, width, height,
- **kwargs):
+ # MGDTODO: Perhaps pass in a Bbox here instead, then the updates will
+ # happen automatically (without needing to call set_x etc.
+ def __init__(self, xy, width, height, **kwargs):
 """
 xy is an x,y tuple lower, left
 
@@ -344,38 +339,41 @@
 
 Patch.__init__(self, **kwargs)
 
- self.xy = list(xy)
- self.width, self.height = width, height
+	self._bbox = transforms.Bbox.from_lbwh(xy[0], xy[1], width, height)
+	self._rect_transform = transforms.BboxTransform(
+	 transforms.Bbox.unit(), self._bbox)
 __init__.__doc__ = cbook.dedent(__init__.__doc__) % artist.kwdocd
 
-
- def get_verts(self):
+ def get_path(self):
 """
 Return the vertices of the rectangle
 """
- x, y = self.xy
- left, right = self.convert_xunits((x, x + self.width))
- bottom, top = self.convert_yunits((y, y + self.height))
+	# This is a "class-static" variable, so all rectangles in the plot
+	# will be shared (and merely have different transforms)
+	return self._path
 
- return npy.array([[left, bottom], [left, top],
-			 [right, top], [right, bottom]],
-			 npy.float_)
+ # MGDTODO: Convert units
+# left, right = self.convert_xunits((x, x + self.width))
+# bottom, top = self.convert_yunits((y, y + self.height))
 
+ def get_transform(self):
+	return self._rect_transform + self._transform
+ 
 def get_x(self):
 "Return the left coord of the rectangle"
- return self.xy[0]
+ return self._bbox.xmin
 
 def get_y(self):
 "Return the bottom coord of the rectangle"
- return self.xy[1]
+ return self._bbox.ymin
 
 def get_width(self):
 "Return the width of the rectangle"
- return self.width
+ return self._bbox.width
 
 def get_height(self):
 "Return the height of the rectangle"
- return self.height
+ return self._bbox.height
 
 def set_x(self, x):
 """
@@ -383,7 +381,7 @@
 
 ACCEPTS: float
 """
- self.xy[0] = x
+ self._bbox.xmin = x
 
 def set_y(self, y):
 """
@@ -391,7 +389,7 @@
 
 ACCEPTS: float
 """
- self.xy[1] = y
+ self._bbox.ymin = y
 
 def set_width(self, w):
 """
@@ -399,7 +397,7 @@
 
 ACCEPTS: float
 """
- self.width = w
+ self._bbox.width = w
 
 def set_height(self, h):
 """
@@ -407,7 +405,7 @@
 
 ACCEPTS: float
 """
- self.height = h
+ self._bbox.height = h
 
 def set_bounds(self, *args):
 """
@@ -419,15 +417,15 @@
 l,b,w,h = args[0]
 else:
 l,b,w,h = args
- self.xy = [l,b]
- self.width = w
- self.height = h
+	self._bbox.bounds = l,b,w,h
 
 
 class RegularPolygon(Patch):
 """
 A regular polygon patch.
 """
+ _polygon_cache = {}
+ 
 def __str__(self):
 return "Poly%d(%g,%g)"%(self.numVertices,self.xy[0],self.xy[1])
 
@@ -444,32 +442,27 @@
 """
 Patch.__init__(self, **kwargs)
 
- self.xy = list(xy)
- self.numVertices = numVertices
- self.radius = radius
- self.orientation = orientation
+	path = self._polygon_cache[numVertices]
+	if path is None:
+	 theta = 2*npy.pi/numVertices * npy.arange(numVertices)
+	 verts = npy.hstack((npy.cos(theta), npy.sin(theta)))
+	 path = Path(verts)
+	 self._polygon_cache[numVertices] = path
 
+	self._path = path
+	self._poly_transform = transforms.Affine2D() \
+	 .scale(radius) \
+	 .rotate(orientation) \
+	 .translate(*xy)
+
 __init__.__doc__ = cbook.dedent(__init__.__doc__) % artist.kwdocd
 
+ def get_path(self):
+	return self._path
 
-
- def get_verts(self):
- theta = 2*npy.pi/self.numVertices*npy.arange(self.numVertices) + \
- self.orientation
- r = float(self.radius)
- x, y = map(float, self.xy)
-
- xs = x + r*npy.cos(theta)
- ys = y + r*npy.sin(theta)
-
- #xs = self.convert_xunits(xs)
- #ys = self.convert_yunits(ys)
-
-
- self.verts = zip(xs, ys)
-
- return self.verts
-
+ def get_transform(self):
+	return self._poly_transform + self._transform
+	
 class Polygon(Patch):
 """
 A general polygon patch.
@@ -485,22 +478,20 @@
 %(Patch)s
 See Patch documentation for additional kwargs
 """
-
+	# MGDTODO: This should encourage the use of numpy arrays of shape Nx2
 Patch.__init__(self, **kwargs)
 if not isinstance(xy, list):
 xy = list(xy)
- self.xy = xy
+	self._path = Path(xy, closed=False)
 __init__.__doc__ = cbook.dedent(__init__.__doc__) % artist.kwdocd
 
-
-
 def get_verts(self):
- xs, ys = zip(*self.xy)[:2]
+	return self._path
+
+ # MGDTODO: Convert units
 xs = self.convert_xunits(xs)
 ys = self.convert_yunits(ys)
- return zip(xs, ys)
 
-
 class Wedge(Polygon):
 def __str__(self):
 return "Wedge(%g,%g)"%self.xy[0]
@@ -516,6 +507,7 @@
 %(Patch)s
 
 """
+	# MGDTODO: Implement me
 xc, yc = center
 rads = (math.pi/180.)*npy.arange(theta1, theta2+0.1*dtheta, dtheta)
 xs = r*npy.cos(rads)+xc
@@ -543,6 +535,7 @@
 Valid kwargs are:
 %(Patch)s
 """
+	# MGDTODO: Implement me
 arrow = npy.array( [
 [ 0.0, 0.1 ], [ 0.0, -0.1],
 [ 0.8, -0.1 ], [ 0.8, -0.3],
@@ -586,6 +579,7 @@
 %(Patch)s
 
 """
+	# MGDTODO: Implement me
 if head_width is None:
 head_width = 3 * width
 if head_length is None:
@@ -659,6 +653,7 @@
 %(Patch)s
 
 """
+	# MGDTODO: Implement me
 self.dpi = dpi
 self.xytip = xytip
 self.xybase = xybase
@@ -731,6 +726,7 @@
 %(Patch)s
 
 """
+	# MGDTODO: Implement me
 self.center = xy
 self.radius = radius
 RegularPolygon.__init__(self, xy,
@@ -767,6 +763,7 @@
 Valid kwargs are:
 %(Patch)s
 """
+	# MGDTODO: Implement me
 Patch.__init__(self, **kwargs)
 
 # self.center = npy.array(xy, npy.float)
@@ -833,6 +830,7 @@
 %(Patch)s
 
 """
+	# MGDTODO: Implement me
 if kwargs.has_key('resolution'):
 import warnings
 warnings.warn('Circle is now scale free. Use CirclePolygon instead!', DeprecationWarning)
Added: branches/transforms/lib/matplotlib/path.py
===================================================================
--- branches/transforms/lib/matplotlib/path.py	 (rev 0)
+++ branches/transforms/lib/matplotlib/path.py	2007年09月14日 17:57:52 UTC (rev 3852)
@@ -0,0 +1,50 @@
+import numpy as npy
+
+class Path:
+ # Path codes
+ STOP = 0
+ MOVETO = 1 # 1 vertex
+ LINETO = 2 # 1 vertex
+ CURVE3 = 3 # 2 vertices
+ CURVE4 = 4 # 3 vertices
+ ###
+ # MGDTODO: I'm not sure these are supported by PS/PDF/SVG,
+ # so if they don't, we probably shouldn't
+ CURVEN = 5
+ CATROM = 6
+ UBSPLINE = 7
+ ####
+ CLOSEPOLY = 0x0F # 0 vertices
+
+ code_type = npy.uint8
+ 
+ def __init__(self, vertices, codes=None, closed=True):
+	self._vertices = npy.asarray(vertices, npy.float_)
+	assert self._vertices.ndim == 2
+	assert self._vertices.shape[1] == 2
+
+	if codes is None:
+	 if closed:
+		codes = self.LINETO * npy.ones(
+		 self._vertices.shape[0] + 1, self.code_type)
+		codes[0] = self.MOVETO
+		codes[-1] = self.CLOSEPOLY
+	 else:
+		codes = self.LINETO * npy.ones(
+		 self._vertices.shape[0], self.code_type)
+		codes[0] = self.MOVETO
+ else:
+	 codes = npy.asarray(codes, self.code_type)
+	self._codes = codes
+	 
+	assert self._codes.ndim == 1
+	# MGDTODO: Maybe we should add some quick-and-dirty check that
+	# the number of vertices is correct for the code array
+
+ def _get_codes(self):
+	return self._codes
+ codes = property(_get_codes)
+
+ def _get_vertices(self):
+	return self._vertices
+ vertices = property(_get_vertices)
Modified: branches/transforms/lib/matplotlib/transforms.py
===================================================================
--- branches/transforms/lib/matplotlib/transforms.py	2007年09月14日 13:03:31 UTC (rev 3851)
+++ branches/transforms/lib/matplotlib/transforms.py	2007年09月14日 17:57:52 UTC (rev 3852)
@@ -403,6 +403,9 @@
 Transform.__init__(self)
 self._inverted = None
 
+ def __array__(self):
+	return self.get_matrix()
+	
 def _do_invalidation(self):
 result = self._inverted is None
 self._inverted = None
Modified: branches/transforms/src/_backend_agg.cpp
===================================================================
--- branches/transforms/src/_backend_agg.cpp	2007年09月14日 13:03:31 UTC (rev 3851)
+++ branches/transforms/src/_backend_agg.cpp	2007年09月14日 17:57:52 UTC (rev 3852)
@@ -341,6 +341,7 @@
 
 }
 
+// MGDTODO: Remove this method (it has been conglomerated into draw_path
 template <class VS>
 void
 RendererAgg::_fill_and_stroke(VS& path,
@@ -1399,68 +1400,6 @@
 }
 
 
-
-
-// Py::Object
-// RendererAgg::draw_path(const Py::Tuple& args) {
-// //draw_path(gc, rgbFace, path, transform)
-// theRasterizer->reset_clipping();
- 
-// _VERBOSE("RendererAgg::draw_path");
-// args.verify_length(4);
- 
-// GCAgg gc = GCAgg(args[0], dpi);
-// facepair_t face = _get_rgba_face(args[1], gc.alpha);
- 
-// agg::path_storage *path;
-// swig_type_info * descr = SWIG_TypeQuery("agg::path_storage *");
-// assert(descr);
-// if (SWIG_ConvertPtr(args[2].ptr(),(void **)(&path), descr, 0) == -1)
-// throw Py::TypeError("Could not convert path_storage");
- 
- 
-// Transformation* mpltransform = static_cast<Transformation*>(args[3].ptr());
- 
-// double a, b, c, d, tx, ty;
-// try {
-// mpltransform->affine_params_api(&a, &b, &c, &d, &tx, &ty);
-// }
-// catch(...) {
-// throw Py::ValueError("Domain error on affine_params_api in RendererAgg::draw_path");
-// }
- 
-// agg::trans_affine xytrans = agg::trans_affine(a,b,c,d,tx,ty);
- 
-// double heightd = double(height);
-// agg::path_storage tpath; // the mpl transformed path
-// bool needNonlinear = mpltransform->need_nonlinear_api();
-// size_t Nx = path->total_vertices();
-// double x, y;
-// unsigned cmd;
-// bool curvy = false;
-// for (size_t i=0; i<Nx; i++) {
-// cmd = path->vertex(i, &x, &y);
-// if (cmd==agg::path_cmd_curve3 || cmd==agg::path_cmd_curve4) curvy=true;
-// if (needNonlinear)
-// try {
-// 	mpltransform->nonlinear_only_api(&x, &y);
-// }
-// catch (...) {
-// 	throw Py::ValueError("Domain error on nonlinear_only_api in RendererAgg::draw_path");
-	
-// }
- 
-// //use agg's transformer?
-// xytrans.transform(&x, &y);
-// y = heightd - y; //flipy
-// tpath.add_vertex(x,y,cmd);
-// }
- 
-// _fill_and_stroke(tpath, gc, face, curvy);
-// return Py::Object();
- 
-// }
-
 /**
 * This is a custom span generator that converts spans in the 
 * 8-bit inverted greyscale font buffer to rgba that agg can use.
@@ -1613,8 +1552,172 @@
 
 }
 
+inline void get_next_vertex(const char* & vertex_i, const char* vertex_end, 
+			 double& x, double& y,
+			 size_t next_vertex_stride, 
+			 size_t next_axis_stride) {
+ if (vertex_i + next_axis_stride >= vertex_end)
+ throw Py::ValueError("Error parsing path. Read past end of vertices");
+ x = *(double*)vertex_i;
+ y = *(double*)(vertex_i + next_axis_stride);
+ vertex_i += next_vertex_stride;
+}
 
+#define GET_NEXT_VERTEX(x, y) get_next_vertex(vertex_i, vertex_end, x, y, next_vertex_stride, next_axis_stride)
+
+
+
 Py::Object
+RendererAgg::convert_to_native_path(const Py::Tuple& args) {
+ _VERBOSE("RendererAgg::draw_image");
+ args.verify_length(2);
+ 
+ Py::Object vertices_obj = args[0];
+ Py::Object codes_obj = args[1];
+ 
+ PyArrayObject* vertices = NULL;
+ PyArrayObject* codes = NULL;
+ PathAgg* path = NULL; 
+
+ try {
+ vertices = (PyArrayObject*)PyArray_ContiguousFromObject
+ (vertices_obj.ptr(), PyArray_DOUBLE, 2, 2);
+ if (!vertices || vertices->nd != 2 || vertices->dimensions[1] != 2)
+ throw Py::ValueError("Invalid vertices array.");
+ codes = (PyArrayObject*)PyArray_ContiguousFromObject
+ (codes_obj.ptr(), PyArray_UINT8, 1, 1);
+ if (!codes) 
+ throw Py::ValueError("Invalid codes array.");
+
+ path = new PathAgg();
+
+ size_t next_vertex_stride = vertices->strides[0];
+ size_t next_axis_stride = vertices->strides[1];
+ size_t code_stride = codes->strides[0];
+
+ const char* vertex_i = vertices->data;
+ const char* code_i = codes->data;
+ const char* vertex_end = vertex_i + (vertices->dimensions[0] * vertices->strides[0]);
+
+ size_t N = codes->dimensions[0];
+ double x0, y0, x1, y1, x2, y2;
+
+ for (size_t i = 0; i < N; ++i) {
+ switch (*(unsigned char*)(code_i)) {
+ case MOVETO:
+	GET_NEXT_VERTEX(x0, y0);
+	path->move_to(x0, y0);
+	_VERBOSE("MOVETO");
+	break;
+ case LINETO:
+	GET_NEXT_VERTEX(x0, y0);
+	path->line_to(x0, y0);
+	_VERBOSE("LINETO");
+	break;
+ case CURVE3:
+	GET_NEXT_VERTEX(x0, y0);
+	GET_NEXT_VERTEX(x1, y1);
+	path->curve3(x0, y0, x1, y1);
+	path->curvy = true;
+	_VERBOSE("CURVE3");
+	break;
+ case CURVE4:
+	GET_NEXT_VERTEX(x0, y0);
+	GET_NEXT_VERTEX(x1, y1);
+	GET_NEXT_VERTEX(x2, y2);
+	path->curve4(x0, y0, x1, y1, x2, y2);
+	path->curvy = true;
+	_VERBOSE("CURVE4");
+	break;
+ case CLOSEPOLY:
+	path->close_polygon();
+	_VERBOSE("CLOSEPOLY");
+	break;
+ }
+ code_i += code_stride;
+ }
+ } catch(...) {
+ Py_XDECREF(vertices);
+ Py_XDECREF(codes);
+ delete path;
+ throw;
+ }
+
+ Py_XDECREF(vertices);
+ Py_XDECREF(codes);
+ 
+ return Py::asObject(path);
+}
+
+Py::Object
+RendererAgg::draw_path(const Py::Tuple& args) {
+ typedef agg::conv_transform<agg::path_storage> transformed_path_t;
+ typedef agg::conv_curve<transformed_path_t> curve_t;
+ typedef agg::conv_stroke<curve_t> stroke_t;
+ typedef agg::conv_dash<curve_t> dash_t;
+ typedef agg::conv_stroke<dash_t> stroke_dash_t;
+ //draw_path(gc, rgbFace, path, transform)
+ theRasterizer->reset_clipping();
+ 
+ _VERBOSE("RendererAgg::draw_path");
+ args.verify_length(4);
+
+ GCAgg gc = GCAgg(args[0], dpi);
+ Py::Object path_obj = args[1];
+ if (!PathAgg::check(path_obj))
+ throw Py::TypeError("Native path object is not of correct type");
+ PathAgg* path = static_cast<PathAgg*>(path_obj.ptr());
+ agg::trans_affine trans = py_sequence_to_agg_transformation_matrix(args[2]);
+ facepair_t face = _get_rgba_face(args[3], gc.alpha);
+
+ trans *= agg::trans_affine_scaling(1.0, -1.0);
+ trans *= agg::trans_affine_translation(0.0, (double)height);
+
+ transformed_path_t tpath(*path, trans);
+ // MGDTODO: See if there is any advantage to only curving if necessary
+ curve_t curve(tpath);
+
+ set_clipbox_rasterizer(gc.cliprect);
+ 
+ if (face.first) {
+ rendererAA->color(face.second);
+ theRasterizer->add_path(curve);
+ agg::render_scanlines(*theRasterizer, *slineP8, *rendererAA);
+ }
+
+ if (gc.linewidth) {
+ if (gc.dasha == NULL) {
+ stroke_t stroke(curve);
+ stroke.width(gc.linewidth);
+ stroke.line_cap(gc.cap);
+ stroke.line_join(gc.join);
+ theRasterizer->add_path(stroke);
+ } else {
+ dash_t dash(curve);
+ for (size_t i = 0; i < (gc.Ndash / 2); ++i)
+	dash.add_dash(gc.dasha[2 * i], gc.dasha[2 * i + 1]);
+ stroke_dash_t stroke(dash);
+ stroke.line_cap(gc.cap);
+ stroke.line_join(gc.join);
+ stroke.width(gc.linewidth);
+ theRasterizer->add_path(stroke); //boyle freeze is herre
+ }
+ 
+ if ( gc.isaa ) {
+ rendererAA->color(gc.color);
+ agg::render_scanlines(*theRasterizer, *slineP8, *rendererAA);
+ }
+ else {
+ rendererBin->color(gc.color);
+ agg::render_scanlines(*theRasterizer, *slineBin, *rendererBin);
+ }
+ }
+ 
+ return Py::Object();
+}
+
+
+Py::Object
 RendererAgg::write_rgba(const Py::Tuple& args) {
 _VERBOSE("RendererAgg::write_rgba");
 
@@ -1949,6 +2052,10 @@
 		 "draw_ellipse(gc, rgbFace, x, y, w, h)\n");
 add_varargs_method("draw_polygon", &RendererAgg::draw_polygon,
 		 "draw_polygon(gc, rgbFace, points)\n");
+ add_varargs_method("draw_path", &RendererAgg::draw_path,
+		 "draw_path(gc, rgbFace, native_path, transform)\n");
+ add_varargs_method("convert_to_native_path", &RendererAgg::convert_to_native_path,
+		 "convert_to_native_path(vertices, codes)\n");
 add_varargs_method("draw_lines", &RendererAgg::draw_lines,
 		 "draw_lines(gc, x, y,)\n");
 add_varargs_method("draw_markers", &RendererAgg::draw_markers,
@@ -1976,10 +2083,13 @@
 
 add_varargs_method("restore_region", &RendererAgg::restore_region,
 		 "restore_region(region)");
- 
- 
 }
 
+void PathAgg::init_type()
+{
+ behaviors().name("PathAgg");
+ behaviors().doc("A native Agg path object");
+}
 
 extern "C"
 DL_EXPORT(void)
Modified: branches/transforms/src/_backend_agg.h
===================================================================
--- branches/transforms/src/_backend_agg.h	2007年09月14日 13:03:31 UTC (rev 3851)
+++ branches/transforms/src/_backend_agg.h	2007年09月14日 17:57:52 UTC (rev 3852)
@@ -39,6 +39,14 @@
 #include "agg_scanline_p.h"
 #include "agg_vcgen_markers_term.h"
 
+// These are copied directly from path.py, and must be kept in sync
+#define STOP 0
+#define MOVETO 1
+#define LINETO 2
+#define CURVE3 3
+#define CURVE4 4
+#define CLOSEPOLY 0x0F
+
 typedef agg::pixfmt_rgba32 pixfmt;
 typedef agg::renderer_base<pixfmt> renderer_base;
 typedef agg::renderer_scanline_aa_solid<renderer_base> renderer_aa;
@@ -163,6 +171,8 @@
 Py::Object draw_markers(const Py::Tuple & args);
 Py::Object draw_text_image(const Py::Tuple & args);
 Py::Object draw_image(const Py::Tuple & args);
+ Py::Object draw_path(const Py::Tuple & args);
+ Py::Object convert_to_native_path(const Py::Tuple & args);
 
 Py::Object write_rgba(const Py::Tuple & args);
 Py::Object write_png(const Py::Tuple & args);
@@ -229,7 +239,22 @@
 agg::path_storage *lastclippath;
 };
 
+// A completely opaque data type used only to pass native path
+// data to/from Python. Python can't do anything with the data
+// other than create and then use it.
+class PathAgg : 
+ public agg::path_storage, 
+ public Py::PythonExtension<PathAgg> {
 
+public:
+ PathAgg() : curvy(false) {}
+
+ static void init_type(void);
+
+ bool curvy;
+};
+
+
 // the extension module
 class _backend_agg_module : public Py::ExtensionModule<_backend_agg_module>
 {
@@ -240,6 +265,7 @@
 
 BufferRegion::init_type();
 RendererAgg::init_type();
+ PathAgg::init_type();
 
 add_keyword_method("RendererAgg", &_backend_agg_module::new_renderer,
 		 "RendererAgg(width, height, dpi)");
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
From: <md...@us...> - 2007年09月17日 13:41:58
Revision: 3854
 http://matplotlib.svn.sourceforge.net/matplotlib/?rev=3854&view=rev
Author: mdboom
Date: 2007年09月17日 06:41:38 -0700 (2007年9月17日)
Log Message:
-----------
Transferring work-in-progress
Modified Paths:
--------------
 branches/transforms/examples/shared_axis_demo.py
 branches/transforms/lib/matplotlib/backend_bases.py
 branches/transforms/lib/matplotlib/backends/backend_agg.py
 branches/transforms/lib/matplotlib/lines.py
 branches/transforms/lib/matplotlib/patches.py
 branches/transforms/lib/matplotlib/path.py
 branches/transforms/src/_backend_agg.cpp
 branches/transforms/src/_backend_agg.h
Modified: branches/transforms/examples/shared_axis_demo.py
===================================================================
--- branches/transforms/examples/shared_axis_demo.py	2007年09月15日 04:01:56 UTC (rev 3853)
+++ branches/transforms/examples/shared_axis_demo.py	2007年09月17日 13:41:38 UTC (rev 3854)
@@ -36,12 +36,12 @@
 s2 = exp(-t)
 s3 = sin(4*pi*t)
 ax1 = subplot(311)
-plot(t,s1)
+plot(t,s1, "bH")
 setp( ax1.get_xticklabels(), fontsize=6)
 
 ## share x only
 ax2 = subplot(312, sharex=ax1)
-plot(t, s2)
+plot(t, s2, "b<")
 # make these tick labels invisible
 setp( ax2.get_xticklabels(), visible=False)
 
Modified: branches/transforms/lib/matplotlib/backend_bases.py
===================================================================
--- branches/transforms/lib/matplotlib/backend_bases.py	2007年09月15日 04:01:56 UTC (rev 3853)
+++ branches/transforms/lib/matplotlib/backend_bases.py	2007年09月17日 13:41:38 UTC (rev 3854)
@@ -36,21 +36,25 @@
 """
 pass
 
+ def _get_cached_native_path(self, path):
+	native_path = self._native_paths.get(path)
+	if native_path is None:
+	 import matplotlib.patches
+	 print "CACHE MISS", path
+	 native_path = self.convert_to_native_path(path)
+	 self._native_paths[path] = native_path
+	return native_path
+ 
 def draw_path(self, gc, path, transform, rgbFace = None):
 	"""
 	Handles the caching of the native path associated with the
 	given path and calls the underlying backend's _draw_path to
 	actually do the drawing.
 	"""
-	native_path = self._native_paths.get(path)
-	if native_path is None:
-	 import matplotlib.patches
-	 print "CACHE MISS", path
-	 native_path = self.convert_to_native_path(path)
-	 self._native_paths[path] = native_path
-	self._draw_path(gc, native_path, transform, rgbFace)
+	native_path = self._get_cached_native_path(path)
+	self._draw_native_path(gc, native_path, transform, rgbFace)
 
- def _draw_path(self, gc, native_path, transform, rgbFace):
+ def _draw_native_path(self, gc, native_path, transform, rgbFace):
 	"""
 	Draw the native path object with the given GraphicsContext and
 	transform. The transform passed in will always be affine.
@@ -107,9 +111,10 @@
 return False
 
 def draw_markers(self, gc, marker_path, marker_trans, path, trans, rgbFace=None):
-	pass
- 
- def _draw_markers(self, bgc, path, rgbFace, x, y, trans):
+	native_marker_path = self._get_cached_native_path(marker_path)
+	self._draw_native_markers(gc, native_marker_path, marker_trans, path, trans, rgbFace)
+	
+ def _draw_native_markers(self, gc, native_marker_path, marker_trans, path, trans, rgbFace=None):
 """
 This method is currently underscore hidden because the
 draw_markers method is being used as a sentinel for newstyle
@@ -130,7 +135,7 @@
 vec6 = transform.as_vec6_val()
 ...backend dependent affine...
 """
- pass
+ raise NotImplementedError
 
 def draw_line_collection(self, segments, transform, clipbox,
 colors, linewidths, linestyle, antialiaseds,
Modified: branches/transforms/lib/matplotlib/backends/backend_agg.py
===================================================================
--- branches/transforms/lib/matplotlib/backends/backend_agg.py	2007年09月15日 04:01:56 UTC (rev 3853)
+++ branches/transforms/lib/matplotlib/backends/backend_agg.py	2007年09月17日 13:41:38 UTC (rev 3854)
@@ -140,7 +140,7 @@
 def convert_to_native_path(self, path):
 	return self._renderer.convert_to_native_path(path.vertices, path.codes)
 
- def _draw_path(self, gc, native_path, transform, rgbFace):
+ def _draw_native_path(self, gc, native_path, transform, rgbFace):
 	return self._renderer.draw_path(gc, native_path, transform.to_values(), rgbFace)
 	
 def draw_arc(self, gcEdge, rgbFace, x, y, width, height, angle1, angle2, rotation):
@@ -172,8 +172,12 @@
 def draw_lines(self, gc, x, y, transform):
 	return self._renderer.draw_lines(gc, x, y, transform.to_values())
 
- def draw_markers(self, gc, path, color, x, y, transform):
-	return self._renderer.draw_markers(gc, path, color, x, y, transform.to_values())
+ def _draw_native_markers(self, gc, native_marker_path, marker_trans, path, trans, rgbFace=None):
+	return self._renderer.draw_markers(
+	 gc,
+	 native_marker_path, marker_trans.to_values(),
+	 path.vertices, path.codes, trans.to_values(),
+	 rgbFace)
 
 def draw_polygon(self, *args):
 	return self._renderer.draw_polygon(*args)
Modified: branches/transforms/lib/matplotlib/lines.py
===================================================================
--- branches/transforms/lib/matplotlib/lines.py	2007年09月15日 04:01:56 UTC (rev 3853)
+++ branches/transforms/lib/matplotlib/lines.py	2007年09月17日 13:41:38 UTC (rev 3854)
@@ -520,7 +520,7 @@
 lineFunc(renderer, gc, self._path)
 	 
 	# MGDTODO: Deal with markers
- if self._marker is not None and False:
+ if self._marker is not None:
 gc = renderer.new_gc()
 self._set_gc_clip(gc)
 gc.set_foreground(self.get_markeredgecolor())
@@ -713,6 +713,9 @@
 pass
 
 def _draw_steps(self, renderer, gc, xt, yt):
+	# MGDTODO: This is a quirky one. The step-plotting part
+	# should probably be moved to where the path is generated
+	# in recache, and then just drawn with _draw_solid
 siz=len(xt)
 if siz<2: return
 xt2=npy.ones((2*siz,), xt.dtype)
@@ -727,323 +730,132 @@
 renderer.draw_lines(gc, xt2, yt2)
 
 def _draw_solid(self, renderer, gc, path):
- # if len(xt)<2: return
 gc.set_linestyle('solid')
 	renderer.draw_path(gc, path, self.get_transform())
 
 
- def _draw_dashed(self, renderer, gc, xt, yt):
- if len(xt)<2: return
+ def _draw_dashed(self, renderer, gc, path):
 gc.set_linestyle('dashed')
 if self._dashSeq is not None:
 gc.set_dashes(0, self._dashSeq)
 
- if self._newstyle:
- renderer.draw_lines(gc, xt, yt, self.get_transform())
- else:
- renderer.draw_lines(gc, xt, yt)
+	renderer.draw_path(gc, path, self.get_transform())
 
 
- def _draw_dash_dot(self, renderer, gc, xt, yt):
- if len(xt)<2: return
+ def _draw_dash_dot(self, renderer, gc, path):
 gc.set_linestyle('dashdot')
- if self._newstyle:
- renderer.draw_lines(gc, xt, yt, self.get_transform())
- else:
- renderer.draw_lines(gc, xt, yt)
+	renderer.draw_path(gc, path, self.get_transform())
 
- def _draw_dotted(self, renderer, gc, xt, yt):
-
- if len(xt)<2: return
+	 
+ def _draw_dotted(self, renderer, gc, path):
 gc.set_linestyle('dotted')
- if self._newstyle:
- renderer.draw_lines(gc, xt, yt, self.get_transform())
- else:
- renderer.draw_lines(gc, xt, yt)
+	renderer.draw_path(gc, path, self.get_transform())
 
- def _draw_point(self, renderer, gc, xt, yt):
+	
+ def _draw_point(self, renderer, gc, path):
+	self._draw_circle(renderer, gc, path, point = True)
 
- r = 0.5 * renderer.points_to_pixels(self._markersize)
- r *= self._point_size_reduction
- gc.set_linewidth(0)
- if r <= 0.5:
- self._draw_pixel(renderer, gc, xt, yt)
- elif r <= 2:
- self._draw_hexagon1(renderer, gc, xt, yt, point=True)
- else:
- self._draw_circle(renderer, gc, xt, yt, point=True)
-
- def _draw_pixel(self, renderer, gc, xt, yt):
- if self._newstyle:
- rgbFace = self._get_rgb_face()
- path = agg.path_storage()
- path.move_to(-0.5, -0.5)
- path.line_to(-0.5, 0.5)
- path.line_to(0.5, 0.5)
- path.line_to(0.5, -0.5)
- renderer.draw_markers(gc, path, rgbFace, xt, yt, self.get_transform())
- else:
- for (x,y) in zip(xt, yt):
- renderer.draw_point(gc, x, y)
-
-
- def _draw_circle(self, renderer, gc, xt, yt, point=False):
-
+ def _draw_pixel(self, renderer, gc, path):
+	rgbFace = self._get_rgb_face()
+	transform = Affine2D().translate(-0.5, -0.5)
+	renderer.draw_markers(gc, Path.unit_rectangle, transform,
+			 path, self.get_transform(), rgbFace)
+	
+	
+ def _draw_circle(self, renderer, gc, path, point=False):
 w = renderer.points_to_pixels(self._markersize)
 if point:
 w *= self._point_size_reduction
+	w *= 0.5
 
-
 rgbFace = self._get_rgb_face()
+	transform = Affine2D().scale(w, w)
+	renderer.draw_markers(
+	 gc, Path.unit_circle(), transform, path, self.get_transform(),
+	 rgbFace)
 
- if self._newstyle:
- N = 50.0
- r = w/2.
- rads = (2*math.pi/N)*npy.arange(N)
- xs = r*npy.cos(rads)
- ys = r*npy.sin(rads)
- # todo: use curve3!
- path = agg.path_storage()
- path.move_to(xs[0], ys[0])
- for x, y in zip(xs[1:], ys[1:]):
- path.line_to(x, y)
 
- path.end_poly()
- renderer.draw_markers(gc, path, rgbFace, xt, yt, self.get_transform())
- else:
- for (x,y) in zip(xt,yt):
- renderer.draw_arc(gc, rgbFace,
- x, y, w, w, 0.0, 360.0, 0.0)
-
-
-
- def _draw_triangle_up(self, renderer, gc, xt, yt):
-
-
+ _triangle_path = Path([[0.0, 1.0], [-1.0, -1.0], [1.0, -1.0]])
+ def _draw_triangle_up(self, renderer, gc, path):
 offset = 0.5*renderer.points_to_pixels(self._markersize)
+	transform = Affine2D().scale(offset, offset)
 rgbFace = self._get_rgb_face()
+	renderer.draw_markers(gc, self._triangle_path, transform,
+			 path, self.get_transform(), rgbFace)
 
- if self._newstyle:
- path = agg.path_storage()
- path.move_to(0, offset)
- path.line_to(-offset, -offset)
- path.line_to(offset, -offset)
- path.end_poly()
- renderer.draw_markers(gc, path, rgbFace, xt, yt, self.get_transform())
- else:
- for (x,y) in zip(xt, yt):
- verts = ( (x, y+offset),
- (x-offset, y-offset),
- (x+offset, y-offset) )
- renderer.draw_polygon(gc, rgbFace, verts)
 
-
- def _draw_triangle_down(self, renderer, gc, xt, yt):
+ def _draw_triangle_down(self, renderer, gc, path):
 offset = 0.5*renderer.points_to_pixels(self._markersize)
+	transform = Affine2D().scale(offset, -offset)
 rgbFace = self._get_rgb_face()
+	renderer.draw_markers(gc, self._triangle_path, transform,
+			 path, self.get_transform(), rgbFace)
 
- if self._newstyle:
-
- path = agg.path_storage()
- path.move_to(-offset, offset)
- path.line_to(offset, offset)
- path.line_to(0, -offset)
- path.end_poly()
-
- renderer.draw_markers(gc, path, rgbFace, xt, yt, self.get_transform())
- else:
- for (x,y) in zip(xt, yt):
- verts = ( (x-offset, y+offset),
- (x+offset, y+offset),
- (x, y-offset))
- renderer.draw_polygon(gc, rgbFace, verts)
-
- def _draw_triangle_left(self, renderer, gc, xt, yt):
+	
+ def _draw_triangle_left(self, renderer, gc, path):
 offset = 0.5*renderer.points_to_pixels(self._markersize)
+	transform = Affine2D().scale(offset, offset).rotate_deg(90)
 rgbFace = self._get_rgb_face()
+	renderer.draw_markers(gc, self._triangle_path, transform,
+			 path, self.get_transform(), rgbFace)
 
- if self._newstyle:
 
- path = agg.path_storage()
- path.move_to(-offset, 0)
- path.line_to(offset, -offset)
- path.line_to(offset, offset)
- path.end_poly()
-
- renderer.draw_markers(gc, path, rgbFace, xt, yt, self.get_transform())
- else:
- for (x,y) in zip(xt, yt):
- verts = ( (x-offset, y),
- (x+offset, y-offset),
- (x+offset, y+offset))
- renderer.draw_polygon(gc, rgbFace, verts)
-
-
- def _draw_triangle_right(self, renderer, gc, xt, yt):
+ def _draw_triangle_right(self, renderer, gc, path):
 offset = 0.5*renderer.points_to_pixels(self._markersize)
+	transform = Affine2D().scale(offset, offset).rotate_deg(-90)
 rgbFace = self._get_rgb_face()
- if self._newstyle:
- path = agg.path_storage()
- path.move_to(offset, 0)
- path.line_to(-offset, -offset)
- path.line_to(-offset, offset)
- path.end_poly()
- renderer.draw_markers(gc, path, rgbFace, xt, yt, self.get_transform())
- else:
- for (x,y) in zip(xt, yt):
- verts = ( (x+offset, y),
- (x-offset, y-offset),
- (x-offset, y+offset))
- renderer.draw_polygon(gc, rgbFace, verts)
+	renderer.draw_markers(gc, self._triangle_path, transform,
+			 path, self.get_transform(), rgbFace)
 
 
-
- def _draw_square(self, renderer, gc, xt, yt):
+ def _draw_square(self, renderer, gc, path):
 side = renderer.points_to_pixels(self._markersize)
- offset = side*0.5
+	transform = Affine2D().translate(-0.5, -0.5).scale(side)
 rgbFace = self._get_rgb_face()
+	renderer.draw_markers(gc, Path.unit_rectangle(), transform,
+			 path, self.get_transform(), rgbFace)
 
- if self._newstyle:
-
- path = agg.path_storage()
- path.move_to(-offset, -offset)
- path.line_to(-offset, offset)
- path.line_to(offset, offset)
- path.line_to(offset, -offset)
- path.end_poly()
-
- renderer.draw_markers(gc, path, rgbFace, xt, yt, self.get_transform())
- else:
-
- for (x,y) in zip(xt, yt):
- renderer.draw_rectangle(
- gc, rgbFace,
- x-offset, y-offset, side, side)
-
- def _draw_diamond(self, renderer, gc, xt, yt):
- offset = 0.6*renderer.points_to_pixels(self._markersize)
+	
+ def _draw_diamond(self, renderer, gc, path):
+ side = renderer.points_to_pixels(self._markersize)
+	transform = Affine2D().translate(0.5, 0.5).rotate_deg(45).scale(side)
 rgbFace = self._get_rgb_face()
- if self._newstyle:
- path = agg.path_storage()
- path.move_to(offset, 0)
- path.line_to(0, -offset)
- path.line_to(-offset, 0)
- path.line_to(0, offset)
- path.end_poly()
+	renderer.draw_markers(gc, Path.unit_rectangle(), transform,
+			 path, self.get_transform(), rgbFace)
 
- renderer.draw_markers(gc, path, rgbFace, xt, yt, self.get_transform())
- else:
-
-
- for (x,y) in zip(xt, yt):
- verts = ( (x+offset, y),
- (x, y-offset),
- (x-offset, y),
- (x, y+offset))
- renderer.draw_polygon(gc, rgbFace, verts)
-
- def _draw_thin_diamond(self, renderer, gc, xt, yt):
- offset = 0.7*renderer.points_to_pixels(self._markersize)
- xoffset = 0.6*offset
+	
+ def _draw_thin_diamond(self, renderer, gc, path):
+ offset = renderer.points_to_pixels(self._markersize)
+	transform = Affine2D().translate(0.5, 0.5).rotate_deg(45).scale(offset * 0.8, offset)
 rgbFace = self._get_rgb_face()
+	renderer.draw_markers(gc, Path.unit_rectangle(), transform,
+			 path, self.get_transform(), rgbFace)
 
- if self._newstyle:
- path = agg.path_storage()
- path.move_to(xoffset, 0)
- path.line_to(0, -offset)
- path.line_to(-xoffset, 0)
- path.line_to(0, offset)
- path.end_poly()
- renderer.draw_markers(gc, path, rgbFace, xt, yt, self.get_transform())
- else:
- for (x,y) in zip(xt, yt):
- verts = ( (x+xoffset, y),
- (x, y-offset),
- (x-xoffset, y),
- (x, y+offset))
- renderer.draw_polygon(gc, rgbFace, verts)
+	
+ def _draw_pentagon(self, renderer, gc, path):
+ offset = 0.5 * renderer.points_to_pixels(self._markersize)
+	transform = Affine2D().scale(offset)
+	rgbFace = self._get_rgb_face()
+	renderer.draw_markers(gc, Path.unit_regular_polygon(5), transform,
+			 path, self.get_transform(), rgbFace)
 
- def _draw_pentagon(self, renderer, gc, xt, yt):
- offset = 0.6*renderer.points_to_pixels(self._markersize)
- offsetX1 = offset*0.95
- offsetY1 = offset*0.31
- offsetX2 = offset*0.59
- offsetY2 = offset*0.81
- rgbFace = self._get_rgb_face()
+	
+ def _draw_hexagon1(self, renderer, gc, path, point=False):
+ offset = 0.5 * renderer.points_to_pixels(self._markersize)
+	transform = Affine2D().scale(offset)
+	rgbFace = self._get_rgb_face()
+	renderer.draw_markers(gc, Path.unit_regular_polygon(6), transform,
+			 path, self.get_transform(), rgbFace)
 
- if self._newstyle:
- path = agg.path_storage()
- path.move_to(0, offset)
- path.line_to(-offsetX1, offsetY1)
- path.line_to(-offsetX2, -offsetY2)
- path.line_to(+offsetX2, -offsetY2)
- path.line_to(+offsetX1, offsetY1)
- path.end_poly()
-
- renderer.draw_markers(gc, path, rgbFace, xt, yt, self.get_transform())
- else:
- for (x,y) in zip(xt, yt):
- verts = ( (x, y+offset),
- (x-offsetX1, y+offsetY1),
- (x-offsetX2, y-offsetY2),
- (x+offsetX2, y-offsetY2),
- (x+offsetX1, y+offsetY1))
- renderer.draw_polygon(gc, rgbFace, verts)
-
- def _draw_hexagon1(self, renderer, gc, xt, yt, point=False):
- offset = 0.6*renderer.points_to_pixels(self._markersize)
- if point:
- offset *= self._point_size_reduction
- offsetX1 = offset*0.87
- offsetY1 = offset*0.5
- rgbFace = self._get_rgb_face()
-
- if self._newstyle:
- path = agg.path_storage()
- path.move_to(0, offset)
- path.line_to(-offsetX1, offsetY1)
- path.line_to(-offsetX1, -offsetY1)
- path.line_to(0, -offset)
- path.line_to(offsetX1, -offsetY1)
- path.line_to(offsetX1, offsetY1)
- path.end_poly()
- renderer.draw_markers(gc, path, rgbFace, xt, yt, self.get_transform())
- else:
- for (x,y) in zip(xt, yt):
- verts = ( (x, y+offset),
- (x-offsetX1, y+offsetY1),
- (x-offsetX1, y-offsetY1),
- (x, y-offset),
- (x+offsetX1, y-offsetY1),
- (x+offsetX1, y+offsetY1))
- renderer.draw_polygon(gc, rgbFace, verts)
-
+	
 def _draw_hexagon2(self, renderer, gc, xt, yt):
- offset = 0.6*renderer.points_to_pixels(self._markersize)
- offsetX1 = offset*0.5
- offsetY1 = offset*0.87
- rgbFace = self._get_rgb_face()
- if self._newstyle:
- path = agg.path_storage()
- path.move_to(offset, 0)
- path.line_to(offsetX1, offsetY1)
- path.line_to(-offsetX1, offsetY1)
- path.line_to(-offset, 0)
- path.line_to(-offsetX1, -offsetY1)
- path.line_to(offsetX1, -offsetY1)
- path.end_poly()
+ offset = 0.5 * renderer.points_to_pixels(self._markersize)
+	transform = Affine2D().scale(offset).rotate_deg(30)
+	rgbFace = self._get_rgb_face()
+	renderer.draw_markers(gc, Path.unit_regular_polygon(6), transform,
+			 path, self.get_transform(), rgbFace)
 
- renderer.draw_markers(gc, path, rgbFace, xt, yt, self.get_transform())
- else:
- for (x,y) in zip(xt, yt):
- verts = ( (x+offset, y),
- (x+offsetX1, y+offsetY1),
- (x-offsetX1, y+offsetY1),
- (x-offset, y),
- (x-offsetX1, y-offsetY1),
- (x+offsetX1, y-offsetY1))
- renderer.draw_polygon(gc, rgbFace, verts)
-
+	
 def _draw_vline(self, renderer, gc, xt, yt):
 offset = 0.5*renderer.points_to_pixels(self._markersize)
 if self._newstyle:
@@ -1055,6 +867,7 @@
 for (x,y) in zip(xt, yt):
 renderer.draw_line(gc, x, y-offset, x, y+offset)
 
+		
 def _draw_hline(self, renderer, gc, xt, yt):
 offset = 0.5*renderer.points_to_pixels(self._markersize)
 if self._newstyle:
@@ -1066,46 +879,31 @@
 for (x,y) in zip(xt, yt):
 renderer.draw_line(gc, x-offset, y, x+offset, y)
 
- def _draw_tickleft(self, renderer, gc, xt, yt):
+ _tickhoriz_path = Path([[0.0, 0.5], [1.0, 0.5]])
+ def _draw_tickleft(self, renderer, gc, path):
 offset = renderer.points_to_pixels(self._markersize)
- if self._newstyle:
- path = agg.path_storage()
- path.move_to(-offset, 0.5)
- path.line_to(0, 0.5)
- renderer.draw_markers(gc, path, None, xt, yt, self.get_transform())
- else:
- for (x,y) in zip(xt, yt):
- renderer.draw_line(gc, x-offset, y, x, y)
+	marker_transform = Affine2D().scale(offset, 1.0)
+	renderer.draw_markers(gc, self._tickhoriz_path, marker_transform,
+			 path, self.get_transform())
 
- def _draw_tickright(self, renderer, gc, xt, yt):
-
+ def _draw_tickright(self, renderer, gc, path):
 offset = renderer.points_to_pixels(self._markersize)
- if self._newstyle:
- path = agg.path_storage()
- path.move_to(0, 0.5)
- path.line_to(offset, 0.5)
- renderer.draw_markers(gc, path, None, xt, yt, self.get_transform())
- else:
- for (x,y) in zip(xt, yt):
- renderer.draw_line(gc, x, y, x+offset, y)
+	marker_transform = Affine2D().scale(-offset, 1.0)
+	renderer.draw_markers(gc, self._tickhoriz_path, marker_transform,
+			 path, self.get_transform())
 
- _tickup_path = Path([[-0.5, 0.0], [-0.5, 1.0]])
- def _draw_tickup(self, renderer, gc, xt, yt):
+ _tickvert_path = Path([[-0.5, 0.0], [-0.5, 1.0]])
+ def _draw_tickup(self, renderer, gc, path):
 offset = renderer.points_to_pixels(self._markersize)
 	marker_transform = Affine2D().scale(1.0, offset)
-	renderer.draw_markers(gc, self._tickup_path, marker_transform,
-			 self._path, self.get_transform())
+	renderer.draw_markers(gc, self._tickvert_path, marker_transform,
+			 path, self.get_transform())
 
- def _draw_tickdown(self, renderer, gc, xt, yt):
+ def _draw_tickdown(self, renderer, gc, path):
 offset = renderer.points_to_pixels(self._markersize)
- if self._newstyle:
- path = agg.path_storage()
- path.move_to(-0.5, -offset)
- path.line_to(-0.5, 0)
- renderer.draw_markers(gc, path, None, xt, yt, self.get_transform())
- else:
- for (x,y) in zip(xt, yt):
- renderer.draw_line(gc, x, y-offset, x, y)
+	marker_transform = Affine2D().scale(1.0, -offset)
+	renderer.draw_markers(gc, self._tickvert_path, marker_transform,
+			 path, self.get_transform())
 
 def _draw_plus(self, renderer, gc, xt, yt):
 offset = 0.5*renderer.points_to_pixels(self._markersize)
Modified: branches/transforms/lib/matplotlib/patches.py
===================================================================
--- branches/transforms/lib/matplotlib/patches.py	2007年09月15日 04:01:56 UTC (rev 3853)
+++ branches/transforms/lib/matplotlib/patches.py	2007年09月17日 13:41:38 UTC (rev 3854)
@@ -288,7 +288,6 @@
 self._update()
 __init__.__doc__ = cbook.dedent(__init__.__doc__) % artist.kwdocd
 
-
 def _update(self):
 self.update_from(self.patch)
 if self.props is not None:
@@ -316,8 +315,7 @@
 
 """
 
- _path = Path(
-	[[0.0, 0.0], [1.0, 0.0], [1.0, 1.0], [0.0, 1.0]])
+ _path = Path.unit_rectangle()
 
 def __str__(self):
 return str(self.__class__).split('.')[-1] \
@@ -424,8 +422,6 @@
 """
 A regular polygon patch.
 """
- _polygon_cache = {}
- 
 def __str__(self):
 return "Poly%d(%g,%g)"%(self.numVertices,self.xy[0],self.xy[1])
 
@@ -442,14 +438,7 @@
 """
 Patch.__init__(self, **kwargs)
 
-	path = self._polygon_cache[numVertices]
-	if path is None:
-	 theta = 2*npy.pi/numVertices * npy.arange(numVertices)
-	 verts = npy.hstack((npy.cos(theta), npy.sin(theta)))
-	 path = Path(verts)
-	 self._polygon_cache[numVertices] = path
-
-	self._path = path
+	self._path = Path.unit_regular_polygon(numVertices)
 	self._poly_transform = transforms.Affine2D() \
 	 .scale(radius) \
 	 .rotate(orientation) \
Modified: branches/transforms/lib/matplotlib/path.py
===================================================================
--- branches/transforms/lib/matplotlib/path.py	2007年09月15日 04:01:56 UTC (rev 3853)
+++ branches/transforms/lib/matplotlib/path.py	2007年09月17日 13:41:38 UTC (rev 3854)
@@ -1,21 +1,25 @@
 import numpy as npy
 
-class Path:
+VALIDATE_PATHS = True
+
+class Path(object):
 # Path codes
 STOP = 0
 MOVETO = 1 # 1 vertex
 LINETO = 2 # 1 vertex
 CURVE3 = 3 # 2 vertices
 CURVE4 = 4 # 3 vertices
+ CLOSEPOLY = 5
 ###
 # MGDTODO: I'm not sure these are supported by PS/PDF/SVG,
 # so if they don't, we probably shouldn't
- CURVEN = 5
- CATROM = 6
- UBSPLINE = 7
+ CURVEN = 6
+ CATROM = 7
+ UBSPLINE = 8
 ####
- CLOSEPOLY = 0x0F # 0 vertices
 
+ NUM_VERTICES = [0, 1, 1, 2, 3, 0]
+ 
 code_type = npy.uint8
 
 def __init__(self, vertices, codes=None, closed=True):
@@ -38,9 +42,14 @@
 	self._codes = codes
 	 
 	assert self._codes.ndim == 1
-	# MGDTODO: Maybe we should add some quick-and-dirty check that
-	# the number of vertices is correct for the code array
 
+	if VALIDATE_PATHS:
+	 i = 0
+	 NUM_VERTICES = self.NUM_VERTICES
+	 for code in codes:
+		i += NUM_VERTICES[code]
+	 assert i == len(self.vertices)
+
 def _get_codes(self):
 	return self._codes
 codes = property(_get_codes)
@@ -48,3 +57,74 @@
 def _get_vertices(self):
 	return self._vertices
 vertices = property(_get_vertices)
+
+ def iter_endpoints(self):
+	i = 0
+	NUM_VERTICES = self.NUM_VERTICES
+	vertices = self.vertices
+	for code in self.codes:
+	 num_vertices = NUM_VERTICES[code]
+	 if num_vertices >= 1:
+		i += num_vertices - 1
+		yield vertices[i]
+		i += 1
+
+ _unit_rectangle = None
+ #@classmethod
+ def unit_rectangle(cls):
+	if cls._unit_rectangle is None:
+	 cls._unit_rectangle = \
+		Path([[0.0, 0.0], [1.0, 0.0], [1.0, 1.0], [0.0, 1.0]])
+	return cls._unit_rectangle
+ unit_rectangle = classmethod(unit_rectangle)
+
+ _unit_regular_polygons = {}
+ #@classmethod
+ def unit_regular_polygon(cls, numVertices):
+	path = cls._unit_regular_polygons.get(numVertices)
+	if path is None:
+	 theta = 2*npy.pi/numVertices * npy.arange(numVertices)
+	 # This is to make sure the polygon always "points-up"
+	 theta += npy.pi / 2.0
+	 verts = npy.vstack((npy.cos(theta), npy.sin(theta))).transpose()
+	 path = Path(verts)
+	 cls._unit_regular_polygons[numVertices] = path
+	return path
+ unit_regular_polygon = classmethod(unit_regular_polygon)
+
+ _unit_circle = None
+ #@classmethod
+ def unit_circle(cls):
+	# MGDTODO: Optimize?
+	if cls._unit_circle is None:
+	 offset = 4.0 * (npy.sqrt(2) - 1) / 3.0
+	 vertices = npy.array(
+		[[-1.0, 0.0],
+		 
+		 [-1.0, offset],
+		 [-offset, 1.0],
+		 [0.0, 1.0],
+		 
+		 [offset, 1.0],
+		 [1.0, offset],
+		 [1.0, 0.0],
+		 
+		 [1.0, -offset],
+		 [offset, -1.0],
+		 [0.0, -1.0],
+		 
+		 [-offset, -1.0],
+		 [-1.0, -offset],
+		 [-1.0, 0.0]],
+		npy.float_)
+	 codes = npy.array(
+		[cls.MOVETO,
+		 cls.CURVE4,
+		 cls.CURVE4,
+		 cls.CURVE4,
+		 cls.CURVE4,
+		 cls.CLOSEPOLY],
+		cls.code_type)
+	 cls._unit_circle = Path(vertices, codes)
+	return cls._unit_circle
+ unit_circle = classmethod(unit_circle)
Modified: branches/transforms/src/_backend_agg.cpp
===================================================================
--- branches/transforms/src/_backend_agg.cpp	2007年09月15日 04:01:56 UTC (rev 3853)
+++ branches/transforms/src/_backend_agg.cpp	2007年09月17日 13:41:38 UTC (rev 3854)
@@ -64,6 +64,20 @@
 Py::Float(seq[5]));
 }
 
+// MGDTODO: Implement this as a nice iterator
+inline void get_next_vertex(const char* & vertex_i, const char* vertex_end, 
+			 double& x, double& y,
+			 size_t next_vertex_stride, 
+			 size_t next_axis_stride) {
+ if (vertex_i + next_axis_stride >= vertex_end)
+ throw Py::ValueError("Error parsing path. Read past end of vertices");
+ x = *(double*)vertex_i;
+ y = *(double*)(vertex_i + next_axis_stride);
+ vertex_i += next_vertex_stride;
+}
+
+#define GET_NEXT_VERTEX(x, y) get_next_vertex(vertex_i, vertex_end, x, y, next_vertex_stride, next_axis_stride)
+
 GCAgg::GCAgg(const Py::Object &gc, double dpi, bool snapto) :
 dpi(dpi), snapto(snapto), isaa(true), linewidth(1.0), alpha(1.0),
 cliprect(NULL), clippath(NULL), 
@@ -1255,146 +1269,134 @@
 
 Py::Object
 RendererAgg::draw_markers(const Py::Tuple& args) {
+ typedef agg::conv_transform<agg::path_storage> transformed_path_t;
+ typedef agg::conv_curve<transformed_path_t> curve_t;
+ typedef agg::conv_stroke<curve_t> stroke_t;
+ typedef agg::conv_dash<curve_t> dash_t;
+ typedef agg::conv_stroke<dash_t> stroke_dash_t;
+
 theRasterizer->reset_clipping();
 
- _VERBOSE("RendererAgg::_draw_markers_cache");
- args.verify_length(6);
+ args.verify_length(7);
 
- _VERBOSE("RendererAgg::_draw_markers_cache setting gc");
 GCAgg gc = GCAgg(args[0], dpi);
+ Py::Object marker_path_obj = args[1];
+ if (!PathAgg::check(marker_path_obj))
+ throw Py::TypeError("Native path object is not of correct type");
+ PathAgg* marker_path = static_cast<PathAgg*>(marker_path_obj.ptr());
+ agg::trans_affine marker_trans = py_sequence_to_agg_transformation_matrix(args[2]);
+ Py::Object vertices_obj = args[3];
+ Py::Object codes_obj = args[4];
+ agg::trans_affine trans = py_sequence_to_agg_transformation_matrix(args[5]);
+ facepair_t face = _get_rgba_face(args[6], gc.alpha);
+
+ // Deal with the difference in y-axis direction
+ marker_trans *= agg::trans_affine_scaling(1.0, -1.0);
+ trans *= agg::trans_affine_scaling(1.0, -1.0);
+ trans *= agg::trans_affine_translation(0.0, (double)height);
 
+ marker_path->rewind(0);
+ transformed_path_t marker_path_transformed(*marker_path, marker_trans);
+ curve_t marker_path_curve(marker_path_transformed);
 
- agg::path_storage *ppath;
- 
- swig_type_info * descr = SWIG_TypeQuery("agg::path_storage *");
- assert(descr);
- if (SWIG_ConvertPtr(args[1].ptr(),(void **)(&ppath), descr, 0) == -1) {
- throw Py::TypeError("Could not convert path_storage");
- }
- facepair_t face = _get_rgba_face(args[2], gc.alpha);
- 
- Py::Object xo = args[3];
- Py::Object yo = args[4];
- 
- PyArrayObject *xa = (PyArrayObject *) PyArray_ContiguousFromObject(xo.ptr(), PyArray_DOUBLE, 1, 1);
- 
- if (xa==NULL)
- throw Py::TypeError("RendererAgg::_draw_markers_cache expected numerix array");
- 
- 
- PyArrayObject *ya = (PyArrayObject *) PyArray_ContiguousFromObject(yo.ptr(), PyArray_DOUBLE, 1, 1);
- 
- if (ya==NULL)
- throw Py::TypeError("RendererAgg::_draw_markers_cache expected numerix array");
- 
- agg::trans_affine xytrans = py_sequence_to_agg_transformation_matrix(args[5]);
- 
- size_t Nx = xa->dimensions[0];
- size_t Ny = ya->dimensions[0];
- 
- if (Nx!=Ny)
- throw Py::ValueError(Printf("x and y must be equal length arrays; found %d and %d", Nx, Ny).str());
- 
- 
- double heightd = double(height);
- 
- 
- ppath->rewind(0);
- ppath->flip_y(0,0);
- typedef agg::conv_curve<agg::path_storage> curve_t;
- curve_t curve(*ppath);
- 
 //maxim's suggestions for cached scanlines
 agg::scanline_storage_aa8 scanlines;
 theRasterizer->reset();
 
 agg::int8u* fillCache = NULL;
- unsigned fillSize = 0;
- if (face.first) {
- theRasterizer->add_path(curve);
+ agg::int8u* strokeCache = NULL;
+ PyArrayObject* vertices = NULL;
+ PyArrayObject* codes = NULL;
+
+ try {
+ vertices = (PyArrayObject*)PyArray_ContiguousFromObject
+ (vertices_obj.ptr(), PyArray_DOUBLE, 2, 2);
+ if (!vertices || vertices->nd != 2 || vertices->dimensions[1] != 2)
+ throw Py::ValueError("Invalid vertices array.");
+ codes = (PyArrayObject*)PyArray_ContiguousFromObject
+ (codes_obj.ptr(), PyArray_UINT8, 1, 1);
+ if (!codes) 
+ throw Py::ValueError("Invalid codes array.");
+
+ unsigned fillSize = 0;
+ if (face.first) {
+ theRasterizer->add_path(marker_path_curve);
+ agg::render_scanlines(*theRasterizer, *slineP8, scanlines);
+ fillSize = scanlines.byte_size();
+ fillCache = new agg::int8u[fillSize]; // or any container
+ scanlines.serialize(fillCache);
+ }
+ 
+ stroke_t stroke(marker_path_curve);
+ stroke.width(gc.linewidth);
+ stroke.line_cap(gc.cap);
+ stroke.line_join(gc.join);
+ theRasterizer->reset();
+ theRasterizer->add_path(stroke);
 agg::render_scanlines(*theRasterizer, *slineP8, scanlines);
- fillSize = scanlines.byte_size();
- fillCache = new agg::int8u[fillSize]; // or any container
- scanlines.serialize(fillCache);
- }
+ unsigned strokeSize = scanlines.byte_size();
+ strokeCache = new agg::int8u[strokeSize]; // or any container
+ scanlines.serialize(strokeCache);
 
- agg::conv_stroke<curve_t> stroke(curve);
- stroke.width(gc.linewidth);
- stroke.line_cap(gc.cap);
- stroke.line_join(gc.join);
- theRasterizer->reset();
- theRasterizer->add_path(stroke);
- agg::render_scanlines(*theRasterizer, *slineP8, scanlines);
- unsigned strokeSize = scanlines.byte_size();
- agg::int8u* strokeCache = new agg::int8u[strokeSize]; // or any container
- scanlines.serialize(strokeCache);
- 
- theRasterizer->reset_clipping();
- 
- 
- if (gc.cliprect==NULL) {
- rendererBase->reset_clipping(true);
- }
- else {
- int l = (int)(gc.cliprect[0]) ;
- int b = (int)(gc.cliprect[1]) ;
- int w = (int)(gc.cliprect[2]) ;
- int h = (int)(gc.cliprect[3]) ;
- rendererBase->clip_box(l, height-(b+h),l+w, height-b);
- }
- 
- 
- double thisx, thisy;
- for (size_t i=0; i<Nx; i++) {
- thisx = *(double *)(xa->data + i*xa->strides[0]);
- thisy = *(double *)(ya->data + i*ya->strides[0]);
-
- // MGDTODO
-// if (mpltransform->need_nonlinear_api())
-// try {
-// 	mpltransform->nonlinear_only_api(&thisx, &thisy);
-// }
-// catch(...) {
-// 	continue;
-// }
+ theRasterizer->reset_clipping();
+ if (gc.cliprect==NULL) {
+ rendererBase->reset_clipping(true);
+ }
+ else {
+ int l = (int)(gc.cliprect[0]) ;
+ int b = (int)(gc.cliprect[1]) ;
+ int w = (int)(gc.cliprect[2]) ;
+ int h = (int)(gc.cliprect[3]) ;
+ rendererBase->clip_box(l, height-(b+h),l+w, height-b);
+ }
 
- xytrans.transform(&thisx, &thisy);
- 
- thisy = heightd - thisy; //flipy
- 
- thisx = (int)thisx + 0.5;
- thisy = (int)thisy + 0.5;
- if (thisx<0) continue;
- if (thisy<0) continue;
- if (thisx>width) continue;
- if (thisy>height) continue;
- 
+ size_t next_vertex_stride = vertices->strides[0];
+ size_t next_axis_stride = vertices->strides[1];
+ size_t code_stride = codes->strides[0];
+
+ const char* vertex_i = vertices->data;
+ const char* code_i = codes->data;
+ const char* vertex_end = vertex_i + (vertices->dimensions[0] * vertices->strides[0]);
+
+ size_t N = codes->dimensions[0];
+ double x, y;
+
 agg::serialized_scanlines_adaptor_aa8 sa;
 agg::serialized_scanlines_adaptor_aa8::embedded_scanline sl;
- 
- if (face.first) {
- //render the fill
- sa.init(fillCache, fillSize, thisx, thisy);
- rendererAA->color(face.second);
- agg::render_scanlines(sa, sl, *rendererAA);
+
+ for (size_t i=0; i < N; i++) {
+ size_t num_vertices = NUM_VERTICES[(int)(*code_i)];
+ if (num_vertices) {
+	for (size_t j=0; j<num_vertices; ++j)
+	 GET_NEXT_VERTEX(x, y);
+	trans.transform(&x, &y);
+	
+	if (face.first) {
+	 //render the fill
+	 sa.init(fillCache, fillSize, x, y);
+	 rendererAA->color(face.second);
+	 agg::render_scanlines(sa, sl, *rendererAA);
+	}
+
+	//render the stroke
+	sa.init(strokeCache, strokeSize, x, y);
+	rendererAA->color(gc.color);
+	agg::render_scanlines(sa, sl, *rendererAA);
+ }
+ code_i += code_stride;
 }
- 
- //render the stroke
- sa.init(strokeCache, strokeSize, thisx, thisy);
- rendererAA->color(gc.color);
- agg::render_scanlines(sa, sl, *rendererAA);
- 
- } //for each marker
+ } catch(...) {
+ Py_XDECREF(vertices);
+ Py_XDECREF(codes);
+ delete[] fillCache;
+ delete[] strokeCache;
+ }
 
- Py_XDECREF(xa);
- Py_XDECREF(ya);
- 
- if (face.first)
- delete [] fillCache;
+ Py_XDECREF(vertices);
+ Py_XDECREF(codes);
+ delete [] fillCache;
 delete [] strokeCache;
 
- //jdh
- _VERBOSE("RendererAgg::_draw_markers_cache done");
 return Py::Object();
 
 }
@@ -1552,21 +1554,6 @@
 
 }
 
-inline void get_next_vertex(const char* & vertex_i, const char* vertex_end, 
-			 double& x, double& y,
-			 size_t next_vertex_stride, 
-			 size_t next_axis_stride) {
- if (vertex_i + next_axis_stride >= vertex_end)
- throw Py::ValueError("Error parsing path. Read past end of vertices");
- x = *(double*)vertex_i;
- y = *(double*)(vertex_i + next_axis_stride);
- vertex_i += next_vertex_stride;
-}
-
-#define GET_NEXT_VERTEX(x, y) get_next_vertex(vertex_i, vertex_end, x, y, next_vertex_stride, next_axis_stride)
-
-
-
 Py::Object
 RendererAgg::convert_to_native_path(const Py::Tuple& args) {
 _VERBOSE("RendererAgg::draw_image");
@@ -2059,7 +2046,7 @@
 add_varargs_method("draw_lines", &RendererAgg::draw_lines,
 		 "draw_lines(gc, x, y,)\n");
 add_varargs_method("draw_markers", &RendererAgg::draw_markers,
-		 "draw_markers(gc, path, x, y)\n");
+		 "draw_markers(gc, marker_path, marker_trans, vertices, codes, rgbFace)\n");
 add_varargs_method("draw_text_image", &RendererAgg::draw_text_image,
 		 "draw_text_image(font_image, x, y, r, g, b, a)\n");
 add_varargs_method("draw_image", &RendererAgg::draw_image,
Modified: branches/transforms/src/_backend_agg.h
===================================================================
--- branches/transforms/src/_backend_agg.h	2007年09月15日 04:01:56 UTC (rev 3853)
+++ branches/transforms/src/_backend_agg.h	2007年09月17日 13:41:38 UTC (rev 3854)
@@ -45,8 +45,10 @@
 #define LINETO 2
 #define CURVE3 3
 #define CURVE4 4
-#define CLOSEPOLY 0x0F
+#define CLOSEPOLY 5
 
+const size_t NUM_VERTICES[] = { 0, 1, 1, 2, 3, 0 };
+
 typedef agg::pixfmt_rgba32 pixfmt;
 typedef agg::renderer_base<pixfmt> renderer_base;
 typedef agg::renderer_scanline_aa_solid<renderer_base> renderer_aa;
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
From: <md...@us...> - 2007年09月18日 16:21:40
Revision: 3855
 http://matplotlib.svn.sourceforge.net/matplotlib/?rev=3855&view=rev
Author: mdboom
Date: 2007年09月18日 09:21:37 -0700 (2007年9月18日)
Log Message:
-----------
More code using new transformation framework. Lots of dead code
removed from backend_agg.cpp/h
Modified Paths:
--------------
 branches/transforms/lib/matplotlib/backend_bases.py
 branches/transforms/lib/matplotlib/backends/backend_agg.py
 branches/transforms/lib/matplotlib/lines.py
 branches/transforms/lib/matplotlib/path.py
 branches/transforms/lib/matplotlib/transforms.py
 branches/transforms/lib/matplotlib/type1font.py
 branches/transforms/src/_backend_agg.cpp
 branches/transforms/src/_backend_agg.h
Modified: branches/transforms/lib/matplotlib/backend_bases.py
===================================================================
--- branches/transforms/lib/matplotlib/backend_bases.py	2007年09月17日 13:41:38 UTC (rev 3854)
+++ branches/transforms/lib/matplotlib/backend_bases.py	2007年09月18日 16:21:37 UTC (rev 3855)
@@ -39,8 +39,7 @@
 def _get_cached_native_path(self, path):
 	native_path = self._native_paths.get(path)
 	if native_path is None:
-	 import matplotlib.patches
-	 print "CACHE MISS", path
+	 # print "CACHE MISS", path
 	 native_path = self.convert_to_native_path(path)
 	 self._native_paths[path] = native_path
 	return native_path
Modified: branches/transforms/lib/matplotlib/backends/backend_agg.py
===================================================================
--- branches/transforms/lib/matplotlib/backends/backend_agg.py	2007年09月17日 13:41:38 UTC (rev 3854)
+++ branches/transforms/lib/matplotlib/backends/backend_agg.py	2007年09月18日 16:21:37 UTC (rev 3855)
@@ -121,13 +121,9 @@
 				 debug=False)
 if __debug__: verbose.report('RendererAgg.__init__ _RendererAgg done',
 'debug-annoying')
- # self.draw_polygon = self._renderer.draw_polygon
- self.draw_rectangle = self._renderer.draw_rectangle
-	# MGDTODO -- remove these lines
- # self.draw_lines = self._renderer.draw_lines
- # self.draw_markers = self._renderer.draw_markers
- self.draw_image = self._renderer.draw_image
 
+	self.convert_to_native_path = self._renderer.convert_to_native_path
+ self.draw_image = self._renderer.draw_image
 self.copy_from_bbox = self._renderer.copy_from_bbox
 self.restore_region = self._renderer.restore_region
 self.mathtext_parser = MathTextParser('Agg')
@@ -137,12 +133,9 @@
 if __debug__: verbose.report('RendererAgg.__init__ done',
 'debug-annoying')
 
- def convert_to_native_path(self, path):
-	return self._renderer.convert_to_native_path(path.vertices, path.codes)
-
- def _draw_native_path(self, gc, native_path, transform, rgbFace):
-	return self._renderer.draw_path(gc, native_path, transform.to_values(), rgbFace)
-	
+ def _draw_native_path(self, gc, path, transform, rgbFace):
+	return self._renderer.draw_path(gc, path, transform.get_matrix(), rgbFace)
+ 
 def draw_arc(self, gcEdge, rgbFace, x, y, width, height, angle1, angle2, rotation):
 """
 Draw an arc centered at x,y with width and height and angles
@@ -175,8 +168,8 @@
 def _draw_native_markers(self, gc, native_marker_path, marker_trans, path, trans, rgbFace=None):
 	return self._renderer.draw_markers(
 	 gc,
-	 native_marker_path, marker_trans.to_values(),
-	 path.vertices, path.codes, trans.to_values(),
+	 native_marker_path, marker_trans.get_matrix(),
+	 path.vertices, path.codes, trans.get_matrix(),
 	 rgbFace)
 
 def draw_polygon(self, *args):
Modified: branches/transforms/lib/matplotlib/lines.py
===================================================================
--- branches/transforms/lib/matplotlib/lines.py	2007年09月17日 13:41:38 UTC (rev 3854)
+++ branches/transforms/lib/matplotlib/lines.py	2007年09月18日 16:21:37 UTC (rev 3855)
@@ -712,6 +712,7 @@
 def _draw_nothing(self, renderer, gc, path):
 pass
 
+ 
 def _draw_steps(self, renderer, gc, xt, yt):
 	# MGDTODO: This is a quirky one. The step-plotting part
 	# should probably be moved to where the path is generated
@@ -729,6 +730,7 @@
 else:
 renderer.draw_lines(gc, xt2, yt2)
 
+	 
 def _draw_solid(self, renderer, gc, path):
 gc.set_linestyle('solid')
 	renderer.draw_path(gc, path, self.get_transform())
@@ -753,8 +755,15 @@
 
 	
 def _draw_point(self, renderer, gc, path):
-	self._draw_circle(renderer, gc, path, point = True)
+ w = renderer.points_to_pixels(self._markersize) * \
+	 self._point_size_reduction * 0.5
+ rgbFace = self._get_rgb_face()
+	transform = Affine2D().scale(w)
+	renderer.draw_markers(
+	 gc, Path.unit_circle(), transform, path, self.get_transform(),
+	 rgbFace)
 
+	
 def _draw_pixel(self, renderer, gc, path):
 	rgbFace = self._get_rgb_face()
 	transform = Affine2D().translate(-0.5, -0.5)
@@ -762,12 +771,8 @@
 			 path, self.get_transform(), rgbFace)
 	
 	
- def _draw_circle(self, renderer, gc, path, point=False):
- w = renderer.points_to_pixels(self._markersize)
- if point:
- w *= self._point_size_reduction
-	w *= 0.5
-
+ def _draw_circle(self, renderer, gc, path):
+ w = renderer.points_to_pixels(self._markersize) * 0.5
 rgbFace = self._get_rgb_face()
 	transform = Affine2D().scale(w, w)
 	renderer.draw_markers(
@@ -826,7 +831,8 @@
 	
 def _draw_thin_diamond(self, renderer, gc, path):
 offset = renderer.points_to_pixels(self._markersize)
-	transform = Affine2D().translate(0.5, 0.5).rotate_deg(45).scale(offset * 0.8, offset)
+	transform = Affine2D().translate(0.5, 0.5) \
+	 .rotate_deg(45).scale(offset * 0.8, offset)
 rgbFace = self._get_rgb_face()
 	renderer.draw_markers(gc, Path.unit_rectangle(), transform,
 			 path, self.get_transform(), rgbFace)
@@ -840,7 +846,7 @@
 			 path, self.get_transform(), rgbFace)
 
 	
- def _draw_hexagon1(self, renderer, gc, path, point=False):
+ def _draw_hexagon1(self, renderer, gc, path):
 offset = 0.5 * renderer.points_to_pixels(self._markersize)
 	transform = Affine2D().scale(offset)
 	rgbFace = self._get_rgb_face()
@@ -848,50 +854,44 @@
 			 path, self.get_transform(), rgbFace)
 
 	
- def _draw_hexagon2(self, renderer, gc, xt, yt):
+ def _draw_hexagon2(self, renderer, gc, path):
 offset = 0.5 * renderer.points_to_pixels(self._markersize)
 	transform = Affine2D().scale(offset).rotate_deg(30)
 	rgbFace = self._get_rgb_face()
 	renderer.draw_markers(gc, Path.unit_regular_polygon(6), transform,
 			 path, self.get_transform(), rgbFace)
 
-	
- def _draw_vline(self, renderer, gc, xt, yt):
+
+ _line_marker_path = Path([[0.0, -1.0], [0.0, 1.0]], closed=False)
+ def _draw_vline(self, renderer, gc, path):
 offset = 0.5*renderer.points_to_pixels(self._markersize)
- if self._newstyle:
- path = agg.path_storage()
- path.move_to(0, -offset)
- path.line_to(0, offset)
- renderer.draw_markers(gc, path, None, xt, yt, self.get_transform())
- else:
- for (x,y) in zip(xt, yt):
- renderer.draw_line(gc, x, y-offset, x, y+offset)
+	transform = Affine2D().scale(offset)
+	renderer.draw_markers(gc, self._line_marker_path, transform,
+			 path, self.get_transform())
 
 		
- def _draw_hline(self, renderer, gc, xt, yt):
+ def _draw_hline(self, renderer, gc, path):
 offset = 0.5*renderer.points_to_pixels(self._markersize)
- if self._newstyle:
- path = agg.path_storage()
- path.move_to(-offset, 0)
- path.line_to(offset, 0)
- renderer.draw_markers(gc, path, None, xt, yt, self.get_transform())
- else:
- for (x,y) in zip(xt, yt):
- renderer.draw_line(gc, x-offset, y, x+offset, y)
+	transform = Affine2D().scale(offset).rotate_deg(90)
+	renderer.draw_markers(gc, self._line_marker_path, transform,
+			 path, self.get_transform())
 
+		
 _tickhoriz_path = Path([[0.0, 0.5], [1.0, 0.5]])
 def _draw_tickleft(self, renderer, gc, path):
 offset = renderer.points_to_pixels(self._markersize)
-	marker_transform = Affine2D().scale(offset, 1.0)
+	marker_transform = Affine2D().scale(-offset, 1.0)
 	renderer.draw_markers(gc, self._tickhoriz_path, marker_transform,
 			 path, self.get_transform())
 
+	
 def _draw_tickright(self, renderer, gc, path):
 offset = renderer.points_to_pixels(self._markersize)
-	marker_transform = Affine2D().scale(-offset, 1.0)
+	marker_transform = Affine2D().scale(offset, 1.0)
 	renderer.draw_markers(gc, self._tickhoriz_path, marker_transform,
 			 path, self.get_transform())
 
+	
 _tickvert_path = Path([[-0.5, 0.0], [-0.5, 1.0]])
 def _draw_tickup(self, renderer, gc, path):
 offset = renderer.points_to_pixels(self._markersize)
@@ -899,174 +899,99 @@
 	renderer.draw_markers(gc, self._tickvert_path, marker_transform,
 			 path, self.get_transform())
 
+	
 def _draw_tickdown(self, renderer, gc, path):
 offset = renderer.points_to_pixels(self._markersize)
 	marker_transform = Affine2D().scale(1.0, -offset)
 	renderer.draw_markers(gc, self._tickvert_path, marker_transform,
 			 path, self.get_transform())
 
- def _draw_plus(self, renderer, gc, xt, yt):
+
+ _plus_path = Path([[-1.0, 0.0], [1.0, 0.0],
+		 [0.0, -1.0], [0.0, 1.0]],
+		 [Path.MOVETO, Path.LINETO,
+		 Path.MOVETO, Path.LINETO])
+ def _draw_plus(self, renderer, gc, path):
 offset = 0.5*renderer.points_to_pixels(self._markersize)
- if self._newstyle:
+	transform = Affine2D().scale(offset)
+	renderer.draw_markers(gc, self._plus_path, transform,
+			 path, self.get_transform())
 
- path = agg.path_storage()
- path.move_to(-offset, 0)
- path.line_to( offset, 0)
- path.move_to( 0, -offset)
- path.line_to( 0, offset)
- renderer.draw_markers(gc, path, None, xt, yt, self.get_transform())
- else:
- for (x,y) in zip(xt, yt):
- renderer.draw_line(gc, x-offset, y, x+offset, y)
- renderer.draw_line(gc, x, y-offset, x, y+offset)
 
- def _draw_tri_down(self, renderer, gc, xt, yt):
+ _tri_path = Path([[0.0, 0.0], [0.0, -1.0],
+		 [0.0, 0.0], [0.8, 0.5],
+		 [0.0, 0.0], [-0.8, 0.5]],
+		 [Path.MOVETO, Path.LINETO,
+		 Path.MOVETO, Path.LINETO,
+		 Path.MOVETO, Path.LINETO])
+ def _draw_tri_down(self, renderer, gc, path):
 offset = 0.5*renderer.points_to_pixels(self._markersize)
- offset1 = offset*0.8
- offset2 = offset*0.5
- if self._newstyle:
- path = agg.path_storage()
- path.move_to(0, 0)
- path.line_to(0, -offset)
- path.move_to(0, 0)
- path.line_to(offset1, offset2)
- path.move_to(0, 0)
- path.line_to(-offset1, offset2)
- renderer.draw_markers(gc, path, None, xt, yt, self.get_transform())
- else:
- for (x,y) in zip(xt, yt):
- renderer.draw_line(gc, x, y, x, y-offset)
- renderer.draw_line(gc, x, y, x+offset1, y+offset2)
- renderer.draw_line(gc, x, y, x-offset1, y+offset2)
+	transform = Affine2D().scale(offset)
+	renderer.draw_markers(gc, self._tri_path, transform,
+			 path, self.get_transform())
 
- def _draw_tri_up(self, renderer, gc, xt, yt):
+	
+ def _draw_tri_up(self, renderer, gc, path):
 offset = 0.5*renderer.points_to_pixels(self._markersize)
- offset1 = offset*0.8
- offset2 = offset*0.5
- if self._newstyle:
- path = agg.path_storage()
- path.move_to(0, 0)
- path.line_to(0, offset)
- path.move_to(0, 0)
- path.line_to(offset1, -offset2)
- path.move_to(0, 0)
- path.line_to(-offset1, -offset2)
- renderer.draw_markers(gc, path, None, xt, yt, self.get_transform())
- else:
- for (x,y) in zip(xt, yt):
- renderer.draw_line(gc, x, y, x, y+offset)
- renderer.draw_line(gc, x, y, x+offset1, y-offset2)
- renderer.draw_line(gc, x, y, x-offset1, y-offset2)
+	transform = Affine2D().scale(offset).rotate_deg(180)
+	renderer.draw_markers(gc, self._tri_path, transform,
+			 path, self.get_transform())
 
- def _draw_tri_left(self, renderer, gc, xt, yt):
- offset = 0.5*renderer.points_to_pixels(self._markersize)
- offset1 = offset*0.8
- offset2 = offset*0.5
- if self._newstyle:
- path = agg.path_storage()
- path.move_to(0, 0)
- path.line_to(-offset, 0)
- path.move_to(0, 0)
- path.line_to(offset2, offset1)
- path.move_to(0, 0)
- path.line_to(offset2, -offset1)
- renderer.draw_markers(gc, path, None, xt, yt, self.get_transform())
- else:
- for (x,y) in zip(xt, yt):
- renderer.draw_line(gc, x, y, x-offset, y)
- renderer.draw_line(gc, x, y, x+offset2, y+offset1)
- renderer.draw_line(gc, x, y, x+offset2, y-offset1)
+	
+ def _draw_tri_left(self, renderer, gc, path):
+	offset = 0.5*renderer.points_to_pixels(self._markersize)
+	transform = Affine2D().scale(offset).rotate_deg(90)
+	renderer.draw_markers(gc, self._tri_path, transform,
+			 path, self.get_transform())
 
- def _draw_tri_right(self, renderer, gc, xt, yt):
- offset = 0.5*renderer.points_to_pixels(self._markersize)
- offset1 = offset*0.8
- offset2 = offset*0.5
- if self._newstyle:
- path = agg.path_storage()
- path.move_to(0, 0)
- path.line_to(offset, 0)
- path.move_to(0, 0)
- path.line_to(-offset2, offset1)
- path.move_to(0, 0)
- path.line_to(-offset2, -offset1)
- renderer.draw_markers(gc, path, None, xt, yt, self.get_transform())
- else:
- for (x,y) in zip(xt, yt):
- renderer.draw_line(gc, x, y, x+offset, y)
- renderer.draw_line(gc, x, y, x-offset2, y+offset1)
- renderer.draw_line(gc, x, y, x-offset2, y-offset1)
+	
+ def _draw_tri_right(self, renderer, gc, path):
+	offset = 0.5*renderer.points_to_pixels(self._markersize)
+	transform = Affine2D().scale(offset).rotate_deg(270)
+	renderer.draw_markers(gc, self._tri_path, transform,
+			 path, self.get_transform())
 
- def _draw_caretdown(self, renderer, gc, xt, yt):
+
+ _caret_path = Path([[-1.0, 1.5], [0.0, 0.0], [1.0, 1.5]], closed=False)
+ def _draw_caretdown(self, renderer, gc, path):
 offset = 0.5*renderer.points_to_pixels(self._markersize)
- offset1 = 1.5*offset
- if self._newstyle:
- path = agg.path_storage()
- path.move_to(-offset, offset1)
- path.line_to(0, 0)
- path.line_to(+offset, offset1)
- renderer.draw_markers(gc, path, None, xt, yt, self.get_transform())
- else:
- for (x,y) in zip(xt, yt):
- renderer.draw_line(gc, x-offset, y+offset1, x, y)
- renderer.draw_line(gc, x, y, x+offset, y+offset1)
+	transform = Affine2D().scale(offset)
+	renderer.draw_markers(gc, self._caret_path, transform,
+			 path, self.get_transform())
 
- def _draw_caretup(self, renderer, gc, xt, yt):
+	
+ def _draw_caretup(self, renderer, gc, path):
 offset = 0.5*renderer.points_to_pixels(self._markersize)
- offset1 = 1.5*offset
- if self._newstyle:
- path = agg.path_storage()
- path.move_to(-offset, -offset1)
- path.line_to(0, 0)
- path.line_to(+offset, -offset1)
- renderer.draw_markers(gc, path, None, xt, yt, self.get_transform())
- else:
- for (x,y) in zip(xt, yt):
- renderer.draw_line(gc, x-offset, y-offset1, x, y)
- renderer.draw_line(gc, x, y, x+offset, y-offset1)
+	transform = Affine2D().scale(offset).rotate_deg(180)
+	renderer.draw_markers(gc, self._caret_path, transform,
+			 path, self.get_transform())
 
- def _draw_caretleft(self, renderer, gc, xt, yt):
+	
+ def _draw_caretleft(self, renderer, gc, path):
 offset = 0.5*renderer.points_to_pixels(self._markersize)
- offset1 = 1.5*offset
- if self._newstyle:
- path = agg.path_storage()
- path.move_to(offset1, -offset)
- path.line_to(0, 0)
- path.line_to(offset1, offset)
- renderer.draw_markers(gc, path, None, xt, yt, self.get_transform())
- else:
- for (x,y) in zip(xt, yt):
- renderer.draw_line(gc, x+offset1, y-offset, x, y)
- renderer.draw_line(gc, x, y, x+offset1, y+offset)
+	transform = Affine2D().scale(offset).rotate_deg(90)
+	renderer.draw_markers(gc, self._caret_path, transform,
+			 path, self.get_transform())
 
- def _draw_caretright(self, renderer, gc, xt, yt):
+	
+ def _draw_caretright(self, renderer, gc, path):
 offset = 0.5*renderer.points_to_pixels(self._markersize)
- offset1 = 1.5*offset
- if self._newstyle:
- path = agg.path_storage()
- path.move_to(-offset1, -offset)
- path.line_to(0, 0)
- path.line_to(-offset1, offset)
- renderer.draw_markers(gc, path, None, xt, yt, self.get_transform())
- else:
- for (x,y) in zip(xt, yt):
- renderer.draw_line(gc, x-offset1, y-offset, x, y)
- renderer.draw_line(gc, x, y, x-offset1, y+offset)
+	transform = Affine2D().scale(offset).rotate_deg(270)
+	renderer.draw_markers(gc, self._caret_path, transform,
+			 path, self.get_transform())
 
+
+ _x_path = Path([[-1.0, -1.0], [1.0, 1.0],
+		 [-1.0, 1.0], [1.0, -1.0]],
+		 [Path.MOVETO, Path.LINETO,
+		 Path.MOVETO, Path.LINETO])
 def _draw_x(self, renderer, gc, xt, yt):
 offset = 0.5*renderer.points_to_pixels(self._markersize)
+	transform = Affine2D().scale(offset)
+	renderer.draw_markers(gc, self._x_path, transform,
+			 path, self.get_transform())
 
- if self._newstyle:
- path = agg.path_storage()
- path.move_to(-offset, -offset)
- path.line_to(offset, offset)
- path.move_to(-offset, offset)
- path.line_to(offset, -offset)
- renderer.draw_markers(gc, path, None, xt, yt, self.get_transform())
- else:
- for (x,y) in zip(xt, yt):
- renderer.draw_line(gc, x-offset, y-offset, x+offset, y+offset)
- renderer.draw_line(gc, x-offset, y+offset, x+offset, y-offset)
-
+	
 def update_from(self, other):
 'copy properties from other to self'
 Artist.update_from(self, other)
Modified: branches/transforms/lib/matplotlib/path.py
===================================================================
--- branches/transforms/lib/matplotlib/path.py	2007年09月17日 13:41:38 UTC (rev 3854)
+++ branches/transforms/lib/matplotlib/path.py	2007年09月18日 16:21:37 UTC (rev 3855)
@@ -50,6 +50,9 @@
 		i += NUM_VERTICES[code]
 	 assert i == len(self.vertices)
 
+ def __repr__(self):
+	return "Path(%s, %s)" % (self.vertices, self.codes)
+	 
 def _get_codes(self):
 	return self._codes
 codes = property(_get_codes)
Modified: branches/transforms/lib/matplotlib/transforms.py
===================================================================
--- branches/transforms/lib/matplotlib/transforms.py	2007年09月17日 13:41:38 UTC (rev 3854)
+++ branches/transforms/lib/matplotlib/transforms.py	2007年09月18日 16:21:37 UTC (rev 3855)
@@ -88,11 +88,13 @@
 intervaly = property(_get_intervaly)
 
 def _get_width(self):
- return self.xmax - self.xmin
+	points = self.get_points()
+	return points[1, 0] - points[0, 0]
 width = property(_get_width)
 
 def _get_height(self):
- return self.ymax - self.ymin
+	points = self.get_points()
+	return points[1, 1] - points[0, 1]
 height = property(_get_height)
 
 def _get_bounds(self):
Modified: branches/transforms/lib/matplotlib/type1font.py
===================================================================
--- branches/transforms/lib/matplotlib/type1font.py	2007年09月17日 13:41:38 UTC (rev 3854)
+++ branches/transforms/lib/matplotlib/type1font.py	2007年09月18日 16:21:37 UTC (rev 3855)
@@ -1,15 +1,15 @@
 """
 A class representing a Type 1 font.
 
-This version merely allows reading in pfa and pfb files, stores the
-data in pfa format, and allows reading the parts of the data in a
-format suitable for embedding in pdf files. A more complete class
-might support subsetting.
+This version merely reads pfa and pfb files and splits them for
+embedding in pdf files. There is no support yet for subsetting or
+anything like that.
 
-Usage: font = Type1Font(filename)
- somefile.write(font.data) # writes out font in pfa format
- len1, len2, len3 = font.lengths() # needed for pdf embedding
+Usage (subject to change):
 
+ font = Type1Font(filename)
+ clear_part, encrypted_part, finale = font.parts
+
 Source: Adobe Technical Note #5040, Supporting Downloadable PostScript
 Language Fonts.
 
@@ -32,8 +32,7 @@
 def _read(self, file):
 rawdata = file.read()
 if not rawdata.startswith(chr(128)):
- self.data = rawdata
- return
+ return rawdata
 
 data = ''
 while len(rawdata) > 0:
@@ -101,4 +100,6 @@
 if __name__ == '__main__':
 import sys
 font = Type1Font(sys.argv[1])
- sys.stdout.write(font.data)
+ parts = font.parts
+ print len(parts[0]), len(parts[1]), len(parts[2])
+
Modified: branches/transforms/src/_backend_agg.cpp
===================================================================
--- branches/transforms/src/_backend_agg.cpp	2007年09月17日 13:41:38 UTC (rev 3854)
+++ branches/transforms/src/_backend_agg.cpp	2007年09月18日 16:21:37 UTC (rev 3855)
@@ -10,7 +10,6 @@
 #include <time.h>
 #include <algorithm>
 
-
 #include "agg_conv_transform.h"
 #include "agg_conv_curve.h"
 #include "agg_scanline_storage_aa.h"
@@ -43,28 +42,48 @@
 #define M_PI_2 1.57079632679489661923
 #endif
 
-agg::trans_affine py_sequence_to_agg_transformation_matrix(const Py::Object& obj) {
- Py::SeqBase<Py::Float> seq;
+/** A helper function to convert from a Numpy affine transformation matrix
+ * to an agg::trans_affine.
+ */
+agg::trans_affine py_to_agg_transformation_matrix(const Py::Object& obj) {
+ PyArrayObject* matrix = NULL;
+ 
+ double a = 1.0, b = 0.0, c = 0.0, d = 1.0, e = 0.0, f = 0.0;
+
 try {
- seq = obj;
- } catch(...) {
- throw Py::ValueError("Transformation matrix must be given as a 6-element list.");
- }
+ matrix = (PyArrayObject*) PyArray_ContiguousFromObject(obj.ptr(), PyArray_DOUBLE, 2, 2);
+ if (!matrix || matrix->nd != 2 || matrix->dimensions[0] != 3 || matrix->dimensions[1] != 3) {
+ throw Py::ValueError("Invalid affine transformation matrix.");
+ }
 
- if (seq.size() != 6) {
- throw Py::ValueError("Transformation matrix must be given as a 6-element list.");
+ size_t stride0 = matrix->strides[0];
+ size_t stride1 = matrix->strides[1];
+ char* row0 = matrix->data;
+ char* row1 = row0 + stride0;
+
+ a = *(double*)(row0);
+ row0 += stride1;
+ c = *(double*)(row0);
+ row0 += stride1;
+ e = *(double*)(row0);
+ 
+ b = *(double*)(row1);
+ row1 += stride1;
+ d = *(double*)(row1);
+ row1 += stride1;
+ f = *(double*)(row1);
+ } catch (...) {
+ Py_XDECREF(matrix);
 }
 
- return agg::trans_affine
- (Py::Float(seq[0]), 
- Py::Float(seq[1]), 
- Py::Float(seq[2]), 
- Py::Float(seq[3]), 
- Py::Float(seq[4]), 
- Py::Float(seq[5]));
+ Py_XDECREF(matrix);
+
+ return agg::trans_affine(a, b, c, d, e, f);
 }
 
-// MGDTODO: Implement this as a nice iterator
+/** Helper function to get the next vertex in a Numpy array of vertices.
+ * Will generally be used through the GET_NEXT_VERTEX macro.
+ */
 inline void get_next_vertex(const char* & vertex_i, const char* vertex_end, 
 			 double& x, double& y,
 			 size_t next_vertex_stride, 
@@ -78,12 +97,18 @@
 
 #define GET_NEXT_VERTEX(x, y) get_next_vertex(vertex_i, vertex_end, x, y, next_vertex_stride, next_axis_stride)
 
+Py::Object BufferRegion::to_string(const Py::Tuple &args) {
+ 
+ // owned=true to prevent memory leak
+ return Py::String(PyString_FromStringAndSize((const char*)aggbuf.data,aggbuf.height*aggbuf.stride), true);
+}
+
+
 GCAgg::GCAgg(const Py::Object &gc, double dpi, bool snapto) :
 dpi(dpi), snapto(snapto), isaa(true), linewidth(1.0), alpha(1.0),
 cliprect(NULL), clippath(NULL), 
 Ndash(0), dashOffset(0.0), dasha(NULL)
 {
- 
 _VERBOSE("GCAgg::GCAgg");
 linewidth = points_to_pixels ( gc.getAttr("_linewidth") ) ;
 alpha = Py::Float( gc.getAttr("_alpha") );
@@ -100,7 +125,6 @@
 GCAgg::_set_antialiased(const Py::Object& gc) {
 _VERBOSE("GCAgg::antialiased");
 isaa = Py::Int( gc.getAttr( "_antialiased") );
- 
 }
 
 agg::rgba
@@ -123,13 +147,12 @@
 return p * dpi/72.0;
 }
 
-
 void
 GCAgg::_set_linecap(const Py::Object& gc) {
 _VERBOSE("GCAgg::_set_linecap");
 
 std::string capstyle = Py::String( gc.getAttr( "_capstyle" ) );
- 
+
 if (capstyle=="butt")
 cap = agg::butt_cap;
 else if (capstyle=="round")
@@ -138,7 +161,6 @@
 cap = agg::square_cap;
 else
 throw Py::ValueError(Printf("GC _capstyle attribute must be one of butt, round, projecting; found %s", capstyle.c_str()).str());
- 
 }
 
 void
@@ -155,7 +177,6 @@
 join = agg::bevel_join;
 else
 throw Py::ValueError(Printf("GC _joinstyle attribute must be one of butt, round, projecting; found %s", joinstyle.c_str()).str());
- 
 }
 
 void
@@ -193,7 +214,7 @@
 }
 }
 
-
+// MGDTODO: Convert directly from Bbox object (numpy)
 void
 GCAgg::_set_clip_rectangle( const Py::Object& gc) {
 //set the clip rectangle from the gc
@@ -204,7 +225,7 @@
 cliprect = NULL;
 
 Py::Object o ( gc.getAttr( "_cliprect" ) );
- if (o.ptr()==Py_None) {
+ if (o.ptr() == Py_None) {
 return;
 }
 
@@ -229,38 +250,18 @@
 
 _VERBOSE("GCAgg::_set_clip_path");
 
- delete clippath;
+ Py_XINCREF(clippath);
 clippath = NULL;
 
- Py::Object o = gc.getAttr( "_clippath" );
+ Py::Object o = gc.getAttr("_clippath");
 if (o.ptr()==Py_None) {
 return;
 }
 
- agg::path_storage *tmppath;
- swig_type_info * descr = SWIG_TypeQuery("agg::path_storage *");
- assert(descr);
- if (SWIG_ConvertPtr(o.ptr(),(void **)(&tmppath), descr, 0) == -1) {
- throw Py::TypeError("Could not convert gc path_storage");
- }
- 
- tmppath->rewind(0);
- clippath = new agg::path_storage();
- clippath->copy_from(*tmppath);
- clippath->rewind(0);
- tmppath->rewind(0);
+ clippath = new PathAgg(o);
 }
 
 
-Py::Object BufferRegion::to_string(const Py::Tuple &args) {
- 
- // owned=true to prevent memory leak
- return Py::String(PyString_FromStringAndSize((const char*)aggbuf.data,aggbuf.height*aggbuf.stride), true);
-}
-
-
-
-
 const size_t
 RendererAgg::PIXELS_PER_INCH(96);
 
@@ -311,19 +312,14 @@
 
 
 void
-RendererAgg::set_clipbox_rasterizer( double *cliprect) {
+RendererAgg::set_clipbox_rasterizer(double *cliprect) {
 //set the clip rectangle from the gc
 
 _VERBOSE("RendererAgg::set_clipbox_rasterizer");
- 
 
 theRasterizer->reset_clipping();
 rendererBase->reset_clipping(true);
 
- //if (cliprect==NULL) {
- // theRasterizer->reset_clipping();
- // rendererBase->reset_clipping(true);
- //}
 if (cliprect!=NULL) {
 
 double l = cliprect[0] ;
@@ -355,273 +351,10 @@
 
 }
 
-// MGDTODO: Remove this method (it has been conglomerated into draw_path
-template <class VS>
-void
-RendererAgg::_fill_and_stroke(VS& path,
-			 const GCAgg& gc,
-			 const facepair_t& face,
-			 bool curvy) {
- typedef agg::conv_curve<VS> curve_t;
- 
- //bool isclippath(gc.clippath!=NULL);
- //if (isclippath) _process_alpha_mask(gc); 
-
- if (face.first) {
- rendererAA->color(face.second);
- if (curvy) {
- curve_t curve(path);
- theRasterizer->add_path(curve);
- }
- else
- theRasterizer->add_path(path);
- 
- /*
- if (isclippath) {
-	typedef agg::pixfmt_amask_adaptor<pixfmt, alpha_mask_type> pixfmt_amask_type;
-	typedef agg::renderer_base<pixfmt_amask_type> amask_ren_type;
-	pixfmt_amask_type pfa(*pixFmt, *alphaMask);
-	amask_ren_type r(pfa);
-	typedef agg::renderer_scanline_aa_solid<amask_ren_type> renderer_type;
-	renderer_type ren(r);
-	ren.color(gc.color);
-	//std::cout << "render clippath" << std::endl;
-	
-	agg::render_scanlines(*theRasterizer, *slineP8, ren);
- }
- else {
-	rendererAA->color(gc.color);
-	agg::render_scanlines(*theRasterizer, *slineP8, *rendererAA);
- }
- */
- agg::render_scanlines(*theRasterizer, *slineP8, *rendererAA);
- }
- 
- //now stroke the edge
- if (gc.linewidth) {
- if (curvy) {
- curve_t curve(path);
- agg::conv_stroke<curve_t> stroke(curve);
- stroke.width(gc.linewidth);
- stroke.line_cap(gc.cap);
- stroke.line_join(gc.join);
- theRasterizer->add_path(stroke);
- }
- else {
- agg::conv_stroke<VS> stroke(path);
- stroke.width(gc.linewidth);
- stroke.line_cap(gc.cap);
- stroke.line_join(gc.join);
- theRasterizer->add_path(stroke);
- }
- 
- 
- /*
- if ( gc.isaa ) {
- if (isclippath) {
-	typedef agg::pixfmt_amask_adaptor<pixfmt, alpha_mask_type> pixfmt_amask_type;
-	typedef agg::renderer_base<pixfmt_amask_type> amask_ren_type;
-	pixfmt_amask_type pfa(*pixFmt, *alphaMask);
-	amask_ren_type r(pfa);
-	typedef agg::renderer_scanline_aa_solid<amask_ren_type> renderer_type;
-	renderer_type ren(r);
-	ren.color(gc.color);
-	//std::cout << "render clippath" << std::endl;
-	
-	agg::render_scanlines(*theRasterizer, *slineP8, ren);
- }
- else {
-	rendererAA->color(gc.color);
-	agg::render_scanlines(*theRasterizer, *slineP8, *rendererAA);
- }
- }
- else {
- if (isclippath) {
-	typedef agg::pixfmt_amask_adaptor<pixfmt, alpha_mask_type> pixfmt_amask_type;
-	typedef agg::renderer_base<pixfmt_amask_type> amask_ren_type;
-	pixfmt_amask_type pfa(*pixFmt, *alphaMask);
-	amask_ren_type r(pfa);
-	typedef agg::renderer_scanline_bin_solid<amask_ren_type> renderer_type;
-	renderer_type ren(r);
-	ren.color(gc.color);
-	agg::render_scanlines(*theRasterizer, *slineP8, ren);
- }
- else{
-	rendererBin->color(gc.color);
-	agg::render_scanlines(*theRasterizer, *slineBin, *rendererBin);
- }
- }
-
- */
- 
- if ( gc.isaa ) {
- rendererAA->color(gc.color);
- agg::render_scanlines(*theRasterizer, *slineP8, *rendererAA);
- }
- else {
- rendererBin->color(gc.color);
- agg::render_scanlines(*theRasterizer, *slineBin, *rendererBin);
- }
- }
- 
-
-}
-
-Py::Object
-RendererAgg::draw_rectangle(const Py::Tuple & args) {
- _VERBOSE("RendererAgg::draw_rectangle");
- args.verify_length(6);
- 
- 
- GCAgg gc = GCAgg(args[0], dpi);
- facepair_t face = _get_rgba_face(args[1], gc.alpha);
- 
- 
- double l = Py::Float( args[2] );
- double b = Py::Float( args[3] );
- double w = Py::Float( args[4] );
- double h = Py::Float( args[5] );
- 
- b = height - (b+h);
- double r = l + w;
- double t = b + h;
- 
- //snapto pixel centers
- l = (int)l + 0.5;
- b = (int)b + 0.5;
- r = (int)r + 0.5;
- t = (int)t + 0.5;
- 
- 
- set_clipbox_rasterizer(gc.cliprect);
- 
- agg::path_storage path;
- 
- 
- path.move_to(l, t);
- path.line_to(r, t);
- path.line_to(r, b);
- path.line_to(l, b);
- path.close_polygon();
- 
- _fill_and_stroke(path, gc, face, false);
- 
- return Py::Object();
- 
-}
-
-Py::Object
-RendererAgg::draw_ellipse(const Py::Tuple& args) {
- _VERBOSE("RendererAgg::draw_ellipse");
- args.verify_length(7);
- 
- GCAgg gc = GCAgg(args[0], dpi);
- facepair_t face = _get_rgba_face(args[1], gc.alpha);
- 
- double x = Py::Float( args[2] );
- double y = Py::Float( args[3] );
- double w = Py::Float( args[4] );
- double h = Py::Float( args[5] );
- double rot = Py::Float( args[6] );
- 
- double r; // rot in radians
- 
- set_clipbox_rasterizer(gc.cliprect);
- 
- // Approximate the ellipse with 4 bezier paths
- agg::path_storage path;
- if (rot == 0.0) // simple case
- {
- path.move_to(x, height-(y+h));
- path.arc_to(w, h, 0.0, false, true, x+w, height-y);
- path.arc_to(w, h, 0.0, false, true, x, height-(y-h));
- path.arc_to(w, h, 0.0, false, true, x-w, height-y);
- path.arc_to(w, h, 0.0, false, true, x, height-(y+h));
- path.close_polygon();
- }
- else // rotate by hand :(
- {
- // deg to rad
- r = rot * (M_PI/180.0);
- path.move_to( x+(cos(r)*w), height-(y+(sin(r)*w)));
- path.arc_to(w, h, -r, false, true, x+(cos(r+M_PI_2*3)*h), height-(y+(sin(r+M_PI_2*3)*h)));
- path.arc_to(w, h, -r, false, true, x+(cos(r+M_PI)*w), height-(y+(sin(r+M_PI)*w)));
- path.arc_to(w, h, -r, false, true, x+(cos(r+M_PI_2)*h), height-(y+(sin(r+M_PI_2)*h)));
- path.arc_to(w, h, -r, false, true, x+(cos(r)*w), height-(y+(sin(r)*w)));
- path.close_polygon();
- }
- 
- _fill_and_stroke(path, gc, face);
- return Py::Object();
- 
-}
-
-Py::Object
-RendererAgg::draw_polygon(const Py::Tuple& args) {
- _VERBOSE("RendererAgg::draw_polygon");
- 
- args.verify_length(3);
- 
- GCAgg gc = GCAgg(args[0], dpi);
- facepair_t face = _get_rgba_face(args[1], gc.alpha);
- 
- Py::SeqBase<Py::Object> points( args[2] );
- 
- set_clipbox_rasterizer(gc.cliprect);
- 
- size_t Npoints = points.length();
- if (Npoints<=0)
- return Py::Object();
- 
- 
- // dump the x.y vertices into a double array for faster look ahead
- // and behind access
- double *xs = new double[Npoints];
- double *ys = new double[Npoints];
- 
- for (size_t i=0; i<Npoints; i++) {
- Py::SeqBase<Py::Object> xy(points[i]);
- xy = Py::Tuple(points[i]);
- xs[i] = Py::Float(xy[0]);
- ys[i] = Py::Float(xy[1]);
- ys[i] = height - ys[i];
- }
- 
- 
- 
- agg::path_storage path;
- for (size_t j=0; j<Npoints; j++) {
- 
- double x = xs[j];
- double y = ys[j];
- 
- //snapto pixel centers
- x = (int)x + 0.5;
- y = (int)y + 0.5;
- 
- if (j==0) path.move_to(x,y);
- else path.line_to(x,y);
- }
- path.close_polygon();
- 
- _fill_and_stroke(path, gc, face, false);
- 
- delete [] xs;
- delete [] ys;
- 
- _VERBOSE("RendererAgg::draw_polygon DONE");
- return Py::Object();
- 
-}
-
-
-
 SnapData
 SafeSnap::snap (const float& x, const float& y) {
 xsnap = (int)x + 0.5;
 ysnap = (int)y + 0.5;
-
-
 
 if ( first || ( (xsnap!=lastxsnap) || (ysnap!=lastysnap) ) ) {
 lastxsnap = xsnap;
@@ -690,9 +423,6 @@
 rb.copy_from(*renderingBuffer, &r, -r.x1, -r.y1);
 BufferRegion* reg = new BufferRegion(buf, r, true);
 return Py::asObject(reg);
- 
- 
- 
 }
 
 Py::Object
@@ -715,25 +445,20 @@
 rendererBase->copy_from(rbuf, 0, region->rect.x1, region->rect.y1);
 
 return Py::Object();
- 
- 
- 
 }
 
-
+/**
+ * Helper function to convert a Python Bbox object to an agg rectangle
+ */
 template<class T>
 agg::rect_base<T>
 RendererAgg::bbox_to_rect(const Py::Object& o) {
 //return the agg::rect for bbox, flipping y
 PyArrayObject *bbox = (PyArrayObject *) PyArray_ContiguousFromObject(o.ptr(), PyArray_DOUBLE, 2, 2);
 
- if (!bbox)
+ if (!bbox || bbox->nd != 2 bbox->dimensions[0] != 2 || bbox->dimensions[1] != 2)
 throw Py::TypeError
 ("Expected a Bbox object.");
- 
- if (bbox->nd != 2 || bbox->dimensions[0] != 2 || bbox->dimensions[1] != 2)
- throw Py::TypeError
- ("Expected a Bbox object.");
 
 double l = bbox->data[0];
 double b = bbox->data[1];
@@ -805,469 +530,8 @@
 return numIntersect;
 }
 
-void RendererAgg::DrawQuadMesh(int meshWidth, int meshHeight, const agg::rgba8 colorArray[], const double xCoords[], const double yCoords[])
-{
- /* draw each quadrilateral */
- //	agg::renderer_primitives<agg::renderer_base<agg::pixfmt_rgba32> > lineRen(*rendererBase);
- int i = 0;
- int j = 0;
- int k = 0;
- double xs[4];
- double ys[4];
- int col[4];
- int numCol;
- double ymin;
- int firstRow;
- double ymax;
- int lastRow;
- for(i=0; i < meshHeight; i++)
- {
- for(j=0; j < meshWidth; j++)
-	{
-	 //currTime = clock();
-	 xs[0] = xCoords[(i * (meshWidth + 1)) + j];
-	 ys[0] = yCoords[(i * (meshWidth + 1)) + j];
-	 xs[1] = xCoords[(i * (meshWidth + 1)) + j+1];
-	 ys[1] = yCoords[(i * (meshWidth + 1)) + j+1];
-	 xs[3] = xCoords[((i+1) * (meshWidth + 1)) + j];
-	 ys[3] = yCoords[((i+1) * (meshWidth + 1)) + j];
-	 xs[2] = xCoords[((i+1) * (meshWidth + 1)) + j+1];
-	 ys[2] = yCoords[((i+1) * (meshWidth + 1)) + j+1];
-	 ymin = std::min(std::min(std::min(ys[0], ys[1]), ys[2]), ys[3]);
-	 ymax = std::max(std::max(std::max(ys[0], ys[1]), ys[2]), ys[3]);
-	 firstRow = (int)(ymin);
-	 lastRow = (int)(ymax);
-	 //timer1 += (clock() - currTime);
-	 //currTime = clock();
-	 //timer2 += (clock() - currTime);
-	 //currTime = clock();
-	 for(k = firstRow; k <= lastRow; k++)
-	 {
-	 numCol = inPolygon(k, xs, ys, col);
-	 if (numCol >= 2) rendererBase->copy_hline(col[0], k, col[1] - 1, colorArray[(i * meshWidth) + j]);
-	 if (numCol == 4) rendererBase->copy_hline(col[2], k, col[3] - 1, colorArray[(i * meshWidth) + j]);
-	 }
-	}
- }
- return;
-}
 
-void RendererAgg::DrawQuadMeshEdges(int meshWidth, int meshHeight, const agg::rgba8 colorArray[], const double xCoords[], const double yCoords[])
-{
- int i, j;
- agg::renderer_primitives<agg::renderer_base<agg::pixfmt_rgba32> > lineRen(*rendererBase);
- agg::rgba8 lc(0, 0, 0, 32);
- lineRen.line_color(lc);
- /* show the vertical edges */
- for(i=0; i <= meshWidth; i++)
- {
- lineRen.move_to((int)(256.0 * (xCoords[i])), (int)(256.0 * (yCoords[i])));
- for(j=1; j <= meshHeight; j++)
-	lineRen.line_to((int)(256.0 *(xCoords[(j * (meshWidth + 1))+i])), (int)(256.0 * (yCoords[(j * (meshWidth + 1))+i])));
- }
- /* show the horizontal edges */
- for(i=0; i <= meshHeight; i++)
- {
- lineRen.move_to((int)(256.0 * (xCoords[i * (meshWidth + 1)])), (int)(256.0 * (yCoords[i * (meshWidth + 1)])));
- for(j=1; j <= meshWidth; j++)
-	lineRen.line_to((int)(256.0 * (xCoords[(i * (meshWidth + 1))+j])), (int)(256.0 * (yCoords[(i * (meshWidth + 1))+j])));
- }
-}
-
-
-
 Py::Object
-RendererAgg::draw_lines(const Py::Tuple& args) {
- 
- _VERBOSE("RendererAgg::draw_lines");
- args.verify_length(4);
-
- Py::Object xo = args[1];
- Py::Object yo = args[2];
-
- PyArrayObject *xa = (PyArrayObject *) PyArray_ContiguousFromObject(xo.ptr(), PyArray_DOUBLE, 1, 1);
-
- if (xa==NULL)
- throw Py::TypeError("RendererAgg::draw_lines expected numerix array");
-
-
- PyArrayObject *ya = (PyArrayObject *) PyArray_ContiguousFromObject(yo.ptr(), PyArray_DOUBLE, 1, 1);
-
- if (ya==NULL)
- throw Py::TypeError("RendererAgg::draw_lines expected numerix array");
-
-
- size_t Nx = xa->dimensions[0];
- size_t Ny = ya->dimensions[0];
-
- if (Nx!=Ny)
- throw Py::ValueError(Printf("x and y must be equal length arrays; found %d and %d", Nx, Ny).str());
-
- // call gc with snapto==True if line len is 2 to fix grid line
- // problem
- bool snapto = false;
- if (Nx==2) {
- // disable subpiel rendering for len(2) horizontal or vertical
- // lines
- double x0 = *(double *)(xa->data + 0*xa->strides[0]);
- double x1 = *(double *)(xa->data + 1*xa->strides[0]);
- double y0 = *(double *)(ya->data + 0*ya->strides[0]);
- double y1 = *(double *)(ya->data + 1*ya->strides[0]);
- snapto = (x0==x1) || (y0==y1);
-
- }
- GCAgg gc = GCAgg(args[0], dpi, snapto);
-
- set_clipbox_rasterizer(gc.cliprect);
- //path_t transpath(path, xytrans);
- _process_alpha_mask(gc);
-
- agg::trans_affine xytrans = py_sequence_to_agg_transformation_matrix(args[3]);
-
- agg::path_storage path;
-
- // MGDTODO
- bool needNonlinear = false;
- // mpltransform->need_nonlinear_api();
-
- double thisx(0.0), thisy(0.0);
- double origdx(0.0), origdy(0.0), origdNorm2(0);
- bool moveto = true;
- double heightd = height;
-
- double lastx(0), lasty(0);
- double lastWrittenx(0), lastWritteny(0);
- bool clipped = false;
- 
- bool haveMin = false, lastMax = true;
- double dnorm2Min(0), dnorm2Max(0);
- double maxX(0), maxY(0), minX(0), minY(0);
- 
- double totdx, totdy, totdot;
- double paradx, parady, paradNorm2;
- double perpdx, perpdy, perpdNorm2;
- 
- int counter = 0;
- //idea: we can skip drawing many lines: lines < 1 pixel in length, lines 
- //outside of the drawing area, and we can combine sequential parallel lines
- //into a single line instead of redrawing lines over the same points.
- //The loop below works a bit like a state machine, where what it does depends 
- //on what it did in the last looping. To test whether sequential lines
- //are close to parallel, I calculate the distance moved perpendicular to the
- //last line. Once it gets too big, the lines cannot be combined.
- for (size_t i=0; i<Nx; i++) {
-
- thisx = *(double *)(xa->data + i*xa->strides[0]);
- thisy = *(double *)(ya->data + i*ya->strides[0]);
-
- if (needNonlinear)
- try {
-	// MGDTODO
- // mpltransform->nonlinear_only_api(&thisx, &thisy);
- }
- catch (...) {
- moveto = true;
- continue;
- }
- if (MPL_isnan64(thisx) || MPL_isnan64(thisy)) {
- moveto = true;
- continue;
- }
- 
- //use agg's transformer?
- xytrans.transform(&thisx, &thisy);
- thisy = heightd - thisy; //flipy
- 
- if (snapto) {
- //disable subpixel rendering for horizontal or vertical lines of len=2
- //because it causes irregular line widths for grids and ticks
- thisx = (int)thisx + 0.5;
- thisy = (int)thisy + 0.5;
- }
- 
- //if we are starting a new path segment, move to the first point + init
- if(moveto){
- path.move_to(thisx, thisy);
- lastx = thisx;
- lasty = thisy;
- origdNorm2 = 0; //resets the orig-vector variables (see if-statement below)
- moveto = false;
- continue;
- }
-
- //don't render line segments less that on pixel long!
- if (fabs(thisx-lastx) < 1.0 && fabs(thisy-lasty) < 1.0 ){
- continue; //don't update lastx this time!
- }
- 
- //skip any lines that are outside the drawing area. Note: More lines
- //could be clipped, but a more involved calculation would be needed
- if( (thisx < 0 && lastx < 0 ) ||
- (thisx > width && lastx > width ) ||
- (thisy < 0 && lasty < 0 ) ||
- (thisy > height && lasty > height) ){
- lastx = thisx;
- lasty = thisy;
- clipped = true; 
- continue;
- }
- 
- //if we have no orig vector, set it to this vector and continue.
- //this orig vector is the reference vector we will build up the line to
- if(origdNorm2 == 0){
- //if we clipped after the moveto but before we got here, redo the moveto
- if(clipped){
- path.move_to(lastx, lasty);
- clipped = false;
- }
- 
- origdx = thisx - lastx;
- origdy = thisy - lasty;
- origdNorm2 = origdx*origdx + origdy*origdy;
- 
- //set all the variables to reflect this new orig vecor
- dnorm2Max = origdNorm2;
- dnorm2Min = 0;
- haveMin = false;
- lastMax = true;
- maxX = thisx;
- maxY = thisy;
- minX = lastx; 
- minY = lasty; 
- 
- lastWrittenx = lastx;
- lastWritteny = lasty; 
- 
- //set the last point seen
- lastx = thisx;
- lasty = thisy; 
- continue;
- }
- 
- //if got to here, then we have an orig vector and we just got 
- //a vector in the sequence.
- 
- //check that the perpendicular distance we have moved from the
- //last written point compared to the line we are building is not too 
- //much. If o is the orig vector (we are building on), and v is the vector 
- //from the last written point to the current point, then the perpendicular 
- //vector is p = v - (o.v)o, and we normalize o (by dividing the 
- //second term by o.o). 
- 
- //get the v vector
- totdx = thisx - lastWrittenx;
- totdy = thisy - lastWritteny;
- totdot = origdx*totdx + origdy*totdy;
- 
- //get the para vector ( = (o.v)o/(o.o) )
- paradx = totdot*origdx/origdNorm2;
- parady = totdot*origdy/origdNorm2;
- paradNorm2 = paradx*paradx + parady*parady;
- 
- //get the perp vector ( = v - para )
- perpdx = totdx - paradx;
- perpdy = totdy - parady; 
- perpdNorm2 = perpdx*perpdx + perpdy*perpdy; 
- 
- //if the perp vector is less than some number of (squared) pixels in size,
- //then merge the current vector
- if(perpdNorm2 < 0.25 ){
- //check if the current vector is parallel or
- //anti-parallel to the orig vector. If it is parallel, test
- //if it is the longest of the vectors we are merging in that direction. 
- //If anti-p, test if it is the longest in the opposite direction (the 
- //min of our final line)
- 
- lastMax = false;
- if(totdot >= 0){
- if(paradNorm2 > dnorm2Max){
- lastMax = true;
- dnorm2Max = paradNorm2;
- maxX = lastWrittenx + paradx;
- maxY = lastWritteny + parady;
- }
- }
- else{
- 
- haveMin = true;
- if(paradNorm2 > dnorm2Min){
- dnorm2Min = paradNorm2;
- minX = lastWrittenx + paradx;
- minY = lastWritteny + parady;
- }
- }
- 
- lastx = thisx;
- lasty = thisy;
- continue;
- }
- 
- //if we get here, then this vector was not similar enough to the line
- //we are building, so we need to draw that line and start the next one.
- 
- //if the line needs to extend in the opposite direction from the direction
- //we are drawing in, move back to we start drawing from back there.
- if(haveMin){
- path.line_to(minX, minY); //would be move_to if not for artifacts
- }
- 
- path.line_to(maxX, maxY);
- 
- //if we clipped some segments between this line and the next line
- //we are starting, we also need to move to the last point.
- if(clipped){
- path.move_to(lastx, lasty);
- }
- else if(!lastMax){
- 	//if the last line was not the longest line, then move back to the end 
- //point of the last line in the sequence. Only do this if not clipped,
- //since in that case lastx,lasty is not part of the line just drawn.
- path.line_to(lastx, lasty); //would be move_to if not for artifacts
- } 
-
- //std::cout << "draw lines (" << lastx << ", " << lasty << ")" << std::endl;
-
- //now reset all the variables to get ready for the next line
- 
- origdx = thisx - lastx;
- origdy = thisy - lasty;
- origdNorm2 = origdx*origdx + origdy*origdy;
- 
- dnorm2Max = origdNorm2;
- dnorm2Min = 0;
- haveMin = false;
- lastMax = true;
- maxX = thisx;
- maxY = thisy;
- minX = lastx; 
- minY = lasty;
- 
- lastWrittenx = lastx;
- lastWritteny = lasty; 
- 
- clipped = false;
- 
- lastx = thisx;
- lasty = thisy;
- 
- counter++;
- }
-
- //draw the last line, which is usually not drawn in the loop
- if(origdNorm2 != 0){
- if(haveMin){
- path.line_to(minX, minY); //would be move_to if not for artifacts
- } 
- 
- path.line_to(maxX, maxY);
- }
- 
- //std::cout << "drew " << counter+1 << " lines" << std::endl;
-
- Py_XDECREF(xa);
- Py_XDECREF(ya);
-
- //typedef agg::conv_transform<agg::path_storage, agg::trans_affine> path_t;
- //path_t transpath(path, xytrans);
- _VERBOSE("RendererAgg::draw_lines rendering lines path");
- _render_lines_path(path, gc);
-
- _VERBOSE("RendererAgg::draw_lines DONE");
- return Py::Object();
-
-}
-
-bool 
-RendererAgg::_process_alpha_mask(const GCAgg& gc)
- //if gc has a clippath set, process the alpha mask and return True,
- //else return False
-{
- if (gc.clippath==NULL) {
- return false;
- }
- if (0 &(gc.clippath==lastclippath)) {
- //std::cout << "seen it" << std::endl;
- return true;
- }
- rendererBaseAlphaMask->clear(agg::gray8(0, 0));
- gc.clippath->rewind(0);
- theRasterizer->add_path(*(gc.clippath));
- rendererAlphaMask->color(agg::gray8(255,255));
- agg::render_scanlines(*theRasterizer, *scanlineAlphaMask, *rendererAlphaMask);
- lastclippath = gc.clippath;
- return true;
-}
-
-template<class PathSource>
-void
-RendererAgg::_render_lines_path(PathSource &path, const GCAgg& gc) {
- _VERBOSE("RendererAgg::_render_lines_path");
- typedef PathSource path_t;
- //typedef agg::conv_transform<agg::path_storage, agg::trans_affine> path_t;
- typedef agg::conv_stroke<path_t> stroke_t;
- typedef agg::conv_dash<path_t> dash_t;
- 
- bool isclippath(gc.clippath!=NULL);
- 
- if (gc.dasha==NULL ) { //no dashes
- stroke_t stroke(path);
- stroke.width(gc.linewidth);
- stroke.line_cap(gc.cap);
- stroke.line_join(gc.join);
- theRasterizer->add_path(stroke);
- }
- else {
- dash_t dash(path);
- 
- //todo: dash.dash_start(gc.dashOffset);
- for (size_t i=0; i<gc.Ndash/2; i+=1)
- dash.add_dash(gc.dasha[2*i], gc.dasha[2*i+1]);
- 
- agg::conv_stroke<dash_t> stroke(dash);
- stroke.line_cap(gc.cap);
- stroke.line_join(gc.join);
- stroke.width(gc.linewidth);
- theRasterizer->add_path(stroke); //boyle freeze is herre
- }
- 
- 
- if ( gc.isaa ) {
- if (isclippath) {
- typedef agg::pixfmt_amask_adaptor<pixfmt, alpha_mask_type> pixfmt_amask_type;
- typedef agg::renderer_base<pixfmt_amask_type> amask_ren_type;
- pixfmt_amask_type pfa(*pixFmt, *alphaMask);
- amask_ren_type r(pfa);
- typedef agg::renderer_scanline_aa_solid<amask_ren_type> renderer_type;
- renderer_type ren(r);
- ren.color(gc.color);
- //std::cout << "render clippath" << std::endl;
- 
- agg::render_scanlines(*theRasterizer, *slineP8, ren);
- }
- else {
- rendererAA->color(gc.color);
- agg::render_scanlines(*theRasterizer, *slineP8, *rendererAA);
- }
- }
- else {
- if (isclippath) {
- typedef agg::pixfmt_amask_adaptor<pixfmt, alpha_mask_type> pixfmt_amask_type;
- typedef agg::renderer_base<pixfmt_amask_type> amask_ren_type;
- pixfmt_amask_type pfa(*pixFmt, *alphaMask);
- amask_ren_type r(pfa);
- typedef agg::renderer_scanline_bin_solid<amask_ren_type> renderer_type;
- renderer_type ren(r);
- ren.color(gc.color);
- agg::render_scanlines(*theRasterizer, *slineP8, ren);
- }
- else{
- rendererBin->color(gc.color);
- agg::render_scanlines(*theRasterizer, *slineBin, *rendererBin);
- }
- }
-}
-
-Py::Object
 RendererAgg::draw_markers(const Py::Tuple& args) {
 typedef agg::conv_transform<agg::path_storage> transformed_path_t;
 typedef agg::conv_curve<transformed_path_t> curve_t;
@@ -1284,10 +548,10 @@
 if (!PathAgg::check(marker_path_obj))
 throw Py::TypeError("Native path object is not of correct type");
 PathAgg* marker_path = static_cast<PathAgg*>(marker_path_obj.ptr());
- agg::trans_affine marker_trans = py_sequence_to_agg_transformation_matrix(args[2]);
+ agg::trans_affine marker_trans = py_to_agg_transformation_matrix(args[2]);
 Py::Object vertices_obj = args[3];
 Py::Object codes_obj = args[4];
- agg::trans_affine trans = py_sequence_to_agg_transformation_matrix(args[5]);
+ agg::trans_affine trans = py_to_agg_transformation_matrix(args[5]);
 facepair_t face = _get_rgba_face(args[6], gc.alpha);
 
 // Deal with the difference in y-axis direction
@@ -1337,7 +601,8 @@
 unsigned strokeSize = scanlines.byte_size();
 strokeCache = new agg::int8u[strokeSize]; // or any container
 scanlines.serialize(strokeCache);
- 
+
+ // MGDTODO: Clean this up and support clippaths as well
 theRasterizer->reset_clipping();
 if (gc.cliprect==NULL) {
 rendererBase->reset_clipping(true);
@@ -1557,14 +822,20 @@
 Py::Object
 RendererAgg::convert_to_native_path(const Py::Tuple& args) {
 _VERBOSE("RendererAgg::draw_image");
- args.verify_length(2);
+ args.verify_length(1);
 
- Py::Object vertices_obj = args[0];
- Py::Object codes_obj = args[1];
+ Py::Object path = args[0];
+
+ return Py::asObject(new PathAgg(path));
+}
+
 
+PathAgg::PathAgg(const Py::Object& path_obj) : curvy(false) {
+ Py::Object vertices_obj = path_obj.getAttr("vertices");
+ Py::Object codes_obj = path_obj.getAttr("codes");
+ 
 PyArrayObject* vertices = NULL;
 PyArrayObject* codes = NULL;
- PathAgg* path = NULL; 
 
 try {
 vertices = (PyArrayObject*)PyArray_ContiguousFromObject
@@ -1576,8 +847,6 @@
 if (!codes) 
 throw Py::ValueError("Invalid codes array.");
 
- path = new PathAgg();
-
 size_t next_vertex_stride = vertices->strides[0];
 size_t next_axis_stride = vertices->strides[1];
 size_t code_stride = codes->strides[0];
@@ -1593,31 +862,31 @@
 switch (*(unsigned char*)(code_i)) {
 case MOVETO:
 	GET_NEXT_VERTEX(x0, y0);
-	path->move_to(x0, y0);
+	move_to(x0, y0);
 	_VERBOSE("MOVETO");
 	break;
 case LINETO:
 	GET_NEXT_VERTEX(x0, y0);
-	path->line_to(x0, y0);
+	line_to(x0, y0);
 	_VERBOSE("LINETO");
 	break;
 case CURVE3:
 	GET_NEXT_VERTEX(x0, y0);
 	GET_NEXT_VERTEX(x1, y1);
-	path->curve3(x0, y0, x1, y1);
-	path->curvy = true;
+	curve3(x0, y0, x1, y1);
+	curvy = true;
 	_VERBOSE("CURVE3");
 	break;
 case CURVE4:
 	GET_NEXT_VERTEX(x0, y0);
 	GET_NEXT_VERTEX(x1, y1);
 	GET_NEXT_VERTEX(x2, y2);
-	path->curve4(x0, y0, x1, y1, x2, y2);
-	path->curvy = true;
+	curve4(x0, y0, x1, y1, x2, y2);
+	curvy = true;
 	_VERBOSE("CURVE4");
 	break;
 case CLOSEPOLY:
-	path->close_polygon();
+	close_polygon();
 	_VERBOSE("CLOSEPOLY");
 	break;
 }
@@ -1626,14 +895,11 @@
 } catch(...) {
 Py_XDECREF(vertices);
 Py_XDECREF(codes);
- delete path;
 throw;
 }
 
 Py_XDECREF(vertices);
 Py_XDECREF(codes);
- 
- return Py::asObject(path);
 }
 
 Py::Object
@@ -1643,7 +909,11 @@
 typedef agg::conv_stroke<curve_t> stroke_t;
 typedef agg::conv_dash<curve_t> dash_t;
 typedef agg::conv_stroke<dash_t> stroke_dash_t;
- //draw_path(gc, rgbFace, path, transform)
+ typedef agg::pixfmt_amask_adaptor<pixfmt, alpha_mask_type> pixfmt_amask_type;
+ typedef agg::renderer_base<pixfmt_amask_type> amask_ren_type;
+ typedef agg::renderer_scanline_aa_solid<amask_ren_type> amask_aa_renderer_type;
+ typedef agg::renderer_scanline_bin_solid<amask_ren_type> amask_bin_renderer_type;
+
 theRasterizer->reset_clipping();
 
 _VERBOSE("RendererAgg::draw_path");
@@ -1654,52 +924,118 @@
 if (!PathAgg::check(path_obj))
 throw Py::TypeError("Native path object is not of correct type");
 PathAgg* path = static_cast<PathAgg*>(path_obj.ptr());
- agg::trans_affine trans = py_sequence_to_agg_transformation_matrix(args[2]);
+ agg::trans_affine trans = py_to_agg_transformation_matrix(args[2]);
 facepair_t face = _get_rgba_face(args[3], gc.alpha);
 
 trans *= agg::trans_affine_scaling(1.0, -1.0);
 trans *= agg::trans_affine_translation(0.0, (double)height);
 
- transformed_path_t tpath(*path, trans);
- // MGDTODO: See if there is any advantage to only curving if necessary
- curve_t curve(tpath);
+ transformed_path_t* tpath = NULL;
+ agg::path_storage new_path;
 
- set_clipbox_rasterizer(gc.cliprect);
- 
- if (face.first) {
- rendererAA->color(face.second);
- theRasterizer->add_path(curve);
- agg::render_scanlines(*theRasterizer, *slineP8, *rendererAA);
+ bool has_clippath = (gc.clippath != NULL);
+
+ if (has_clippath && (gc.clippath != lastclippath || trans != lastclippath_transform)) {
+ rendererBaseAlphaMask->clear(agg::gray8(0, 0));
+ gc.clippath->rewind(0);
+ transformed_path_t transformed_clippath(*(gc.clippath), trans);
+ theRasterizer->add_path(transformed_clippath);
+ rendererAlphaMask->color(agg::gray8(255, 255));
+ agg::render_scanlines(*theRasterizer, *scanlineAlphaMask, *rendererAlphaMask);
+ lastclippath = gc.clippath;
+ lastclippath_transform = trans;
 }
 
- if (gc.linewidth) {
- if (gc.dasha == NULL) {
- stroke_t stroke(curve);
- stroke.width(gc.linewidth);
- stroke.line_cap(gc.cap);
- stroke.line_join(gc.join);
- theRasterizer->add_path(stroke);
- } else {
- dash_t dash(curve);
- for (size_t i = 0; i < (gc.Ndash / 2); ++i)
-	dash.add_dash(gc.dasha[2 * i], gc.dasha[2 * i + 1]);
- stroke_dash_t stroke(dash);
- stroke.line_cap(gc.cap);
- stroke.line_join(gc.join);
- stroke.width(gc.linewidth);
- theRasterizer->add_path(stroke); //boyle freeze is herre
+ try {
+ // If this is a straight horizontal or vertical line, quantize to nearest 
+ // pixels
+ if (path->total_vertices() == 2) {
+ double x0, y0, x1, y1;
+ path->vertex(0, &x0, &y0);
+ trans.transform(&x0, &y0);
+ path->vertex(1, &x1, &y1);
+ trans.transform(&x1, &y1);
+ if (((int)x0 == (int)x1) || ((int)y0 == (int)y1)) {
+	new_path.move_to((int)x0 + 0.5, (int)y0 + 0.5);
+	new_path.line_to((int)x1 + 0.5, (int)y1 + 0.5);
+	tpath = new transformed_path_t(new_path, agg::trans_affine());
+ }
 }
+
+ if (!tpath) {
+ tpath = new transformed_path_t(*path, trans);
+ }
+
+ // Benchmarking shows that there is no noticable slowdown to always
+ // treating paths as having curved segments. Doing so greatly 
+ // simplifies the code
+ curve_t curve(*tpath);
 
- if ( gc.isaa ) {
- rendererAA->color(gc.color);
- agg::render_scanlines(*theRasterizer, *slineP8, *rendererAA);
+ set_clipbox_rasterizer(gc.cliprect);
+ 
+ if (face.first) {
+ if (has_clippath) {
+	pixfmt_amask_type pfa(*pixFmt, *alphaMask);
+	amask_ren_type r(pfa);
+	amask_aa_renderer_type ren(r);
+	ren.color(gc.color);
+	agg::render_scanlines(*theRasterizer, *slineP8, ren);
+ } else{
+	rendererAA->color(face.second);
+	theRasterizer->add_path(curve);
+	agg::render_scanlines(*theRasterizer, *slineP8, *rendererAA);
+ }
 }
- else {
- rendererBin->color(gc.color);
- agg::render_scanlines(*theRasterizer, *slineBin, *rendererBin);
+ 
+ if (gc.linewidth) {
+ if (gc.dasha == NULL) {
+	stroke_t stroke(curve);
+	stroke.width(gc.linewidth);
+	stroke.line_cap(gc.cap);
+	stroke.line_join(gc.join);
+	theRasterizer->add_path(stroke);
+ } else {
+ 	dash_t dash(curve);
+	for (size_t i = 0; i < (gc.Ndash / 2); ++i)
+	dash.add_dash(gc.dasha[2 * i], gc.dasha[2 * i + 1]);
+	stroke_dash_t stroke(dash);
+	stroke.line_cap(gc.cap);
+	stroke.line_join(gc.join);
+	stroke.width(gc.linewidth);
+	theRasterizer->add_path(stroke);
+ }
+ 
+ if (gc.isaa) {
+	if (has_clippath) {
+	 pixfmt_amask_type pfa(*pixFmt, *alphaMask);
+	 amask_ren_type r(pfa);
+	 amask_aa_renderer_type ren(r);
+	 ren.color(gc.color);
+	 agg::render_scanlines(*theRasterizer, *slineP8, ren);
+	} else {
+	 rendererAA->color(gc.color);
+	 agg::render_scanlines(*theRasterizer, *slineP8, *rendererAA);
+	}
+ } else {
+	if (has_clippath) {
+	 pixfmt_amask_type pfa(*pixFmt, *alphaMask);
+	 amask_ren_type r(pfa);
+	 amask_bin_renderer_type ren(r);
+	 ren.color(gc.color);
+	 agg::render_scanlines(*theRasterizer, *slineP8, ren);
+	} else {
+	 rendererBin->color(gc.color);
+	 agg::render_scanlines(*theRasterizer, *slineBin, *rendererBin);
+	}
+ }
 }
+ } catch (...) {
+ delete tpath;
+ throw;
 }
 
+ delete tpath;
+
 return Py::Object();
 }
 
@@ -2033,18 +1369,10 @@
 behaviors().name("RendererAgg");
 behaviors().doc("The agg backend extension module");
 
- add_varargs_method("draw_rectangle", &RendererAgg::draw_rectangle,
-		 "draw_rectangle(gc, rgbFace, l, b, w, h)\n");
- add_varargs_method("draw_ellipse", &RendererAgg::draw_ellipse,
-		 "draw_ellipse(gc, rgbFace, x, y, w, h)\n");
- add_varargs_method("draw_polygon", &RendererAgg::draw_polygon,
-		 "draw_polygon(gc, rgbFace, points)\n");
 add_varargs_method("draw_path",...
 
[truncated message content]
From: <md...@us...> - 2007年09月18日 19:29:24
Revision: 3856
 http://matplotlib.svn.sourceforge.net/matplotlib/?rev=3856&view=rev
Author: mdboom
Date: 2007年09月18日 12:29:21 -0700 (2007年9月18日)
Log Message:
-----------
Optimize shared axes (to prevent calling set_xlim/set_ylim more than
once per axes per update).
Save figure at correct dpi.
General cleanup and optimizations.
Modified Paths:
--------------
 branches/transforms/lib/matplotlib/axes.py
 branches/transforms/lib/matplotlib/axis.py
 branches/transforms/lib/matplotlib/backend_bases.py
 branches/transforms/lib/matplotlib/backends/backend_agg.py
 branches/transforms/lib/matplotlib/backends/backend_gtkagg.py
 branches/transforms/lib/matplotlib/backends/backend_tkagg.py
 branches/transforms/lib/matplotlib/cbook.py
 branches/transforms/lib/matplotlib/figure.py
 branches/transforms/lib/matplotlib/legend.py
 branches/transforms/lib/matplotlib/lines.py
 branches/transforms/lib/matplotlib/transforms.py
 branches/transforms/src/_backend_agg.cpp
Modified: branches/transforms/lib/matplotlib/axes.py
===================================================================
--- branches/transforms/lib/matplotlib/axes.py	2007年09月18日 16:21:37 UTC (rev 3855)
+++ branches/transforms/lib/matplotlib/axes.py	2007年09月18日 19:29:21 UTC (rev 3856)
@@ -435,6 +435,9 @@
 1 : 'log',
 }
 
+ _shared_x_axes = cbook.Grouper()
+ _shared_y_axes = cbook.Grouper()
+ 
 def __str__(self):
 return "Axes(%g,%g;%gx%g)" % tuple(self._position.bounds)
 def __init__(self, fig, rect,
@@ -491,6 +494,10 @@
 # must be set before set_figure
 self._sharex = sharex
 self._sharey = sharey
+	if sharex is not None:
+	 self._shared_x_axes.join(self, sharex)
+	if sharey is not None:
+	 self._shared_y_axes.join(self, sharey)
 # Flag: True if some other Axes instance is sharing our x or y axis
 self._masterx = False
 self._mastery = False
@@ -502,7 +509,6 @@
 # this call may differ for non-sep axes, eg polar
 self._init_axis()
 
-
 if axisbg is None: axisbg = rcParams['axes.facecolor']
 self._axisbg = axisbg
 self._frameon = frameon
@@ -616,55 +622,28 @@
 #these will be updated later as data is added
 self._set_lim_and_transforms()
 
- def _shared_xlim_callback(self, ax):
-	xmin, xmax = ax.get_xlim()
-	self.set_xlim(xmin, xmax, emit=False)
-	self.figure.canvas.draw_idle()
-
- def _shared_ylim_callback(self, ax):
-	ymin, ymax = ax.get_ylim()
-	self.set_ylim(ymin, ymax, emit=False)
-	self.figure.canvas.draw_idle()
-	
 def _set_lim_and_transforms(self):
 """
 set the dataLim and viewLim BBox attributes and the
 transData and transAxes Transformation attributes
 """
-	Bbox = mtransforms.Bbox
-	self.viewLim = Bbox.unit()
+	self.viewLim = mtransforms.Bbox.unit()
+	self.dataLim = mtransforms.Bbox.unit()
 	
- if self._sharex is not None:
-	 # MGDTODO: This may be doing at least one too many updates
-	 # than necessary
-	 self._sharex.callbacks.connect(
- 		'xlim_changed', self._shared_xlim_callback)
-	 self.viewLim.intervalx = self._sharex.viewLim.intervalx
- if self._sharey is not None:
- 	 self._sharey.callbacks.connect(
- 		'ylim_changed', self._shared_ylim_callback)
-	 self.viewLim.intervaly = self._sharex.viewLim.intervaly
-
-	self.dataLim = Bbox.unit()
-	
 self.transAxes = mtransforms.BboxTransform(
- Bbox.unit(), self.bbox)
-
+ mtransforms.Bbox.unit(), self.bbox)
 self.transData = mtransforms.BboxTransform(
 self.viewLim, self.bbox)
 	 
 	 
 def get_position(self, original=False):
 'Return the axes rectangle left, bottom, width, height'
-	# MGDTODO: This changed from returning a list to returning a Bbox
-	# If you get any errors with the result of this function, please
-	# update the calling code
 if original:
- return copy.copy(self._originalPosition)
+ return self._originalPosition
 else:
- return copy.copy(self._position)
-	 # return [val.get() for val in self._position]
+ return self._position
 
+	
 def set_position(self, pos, which='both'):
 """
 Set the axes position with pos = [left, bottom, width, height]
@@ -699,8 +678,7 @@
 self.xaxis.cla()
 self.yaxis.cla()
 
-	# MGDTODO
- # self.dataLim.ignore(1)
+	self.ignore_existing_data_limits = True
 self.callbacks = cbook.CallbackRegistry(('xlim_changed', 'ylim_changed'))
 
 if self._sharex is not None:
@@ -886,7 +864,7 @@
 return
 
 
- l,b,w,h = self.get_position(original=True)
+ l,b,w,h = self.get_position(original=True).bounds
 box_aspect = fig_aspect * (h/w)
 data_ratio = box_aspect / A
 
@@ -1152,7 +1130,7 @@
 # Otherwise, it will compute the bounds of it's current data
 # and the data in xydata
 xys = npy.asarray(xys)
- self.dataLim.update_numerix_xy(xys, -1)
+ self.update_datalim_numerix(xys[:, 0], xys[:, 1])
 
 
 def update_datalim_numerix(self, x, y):
@@ -1161,10 +1139,9 @@
 # limits and set the bound to be the bounds of the xydata.
 # Otherwise, it will compute the bounds of it's current data
 # and the data in xydata
- #print type(x), type(y)
-	# MGDTODO
 ## self.dataLim.update_numerix(x, y, -1)
-	self.dataLim.update_from_data(x, y)
+	self.dataLim.update_from_data(x, y, self.ignore_existing_data_limits)
+	self.ignore_existing_data_limits = False
 
 def _get_verts_in_data_coords(self, trans, xys):
 if trans == self.transData:
@@ -1264,9 +1241,7 @@
 if not self.get_visible(): return
 renderer.open_group('axes')
 self.apply_aspect()
-	# MGDTODO -- this is where we can finalize all of the transforms
- # self.transData.freeze() # eval the lazy objects
- # self.transAxes.freeze()
+
 if self.axison and self._frameon: self.axesPatch.draw(renderer)
 artists = []
 
@@ -1314,17 +1289,13 @@
 if self.axison and self._frameon:
 artists.append(self.axesFrame)
 
- # keep track of i to guarantee stable sort for python 2.2
- dsu = [ (a.zorder, i, a) for i, a in enumerate(artists)
- if not a.get_animated()]
+	dsu = [ (a.zorder, a) for a in artists
+		if not a.get_animated() ]
 dsu.sort()
 
- for zorder, i, a in dsu:
+ for zorder, a in dsu:
 a.draw(renderer)
 
-	# MGDTODO
-	# self.transData.thaw() # release the lazy objects
- # self.transAxes.thaw() # release the lazy objects
 renderer.close_group('axes')
 self._cachedRenderer = renderer
 
@@ -1509,7 +1480,6 @@
 
 ACCEPTS: len(2) sequence of floats
 """
-
 if xmax is None and iterable(xmin):
 xmin,xmax = xmin
 
@@ -1534,11 +1504,10 @@
 	self.viewLim.intervalx = (xmin, xmax)
 if emit:
 	 self.callbacks.process('xlim_changed', self)
-	 # MGDTODO: It would be nice to do this is in the above callback list,
-	 # but it's difficult to tell how to initialize this at the
-	 # right time
-	 if self._sharex:
-		self._sharex.set_xlim(*self.viewLim.intervalx)
+	 # Call all of the other x-axes that are shared with this one
+	 for other in self._shared_x_axes.get_siblings(self):
+		if other is not self:
+		 other.set_xlim(self.viewLim.xmin, self.viewLim.xmax, emit=False)
 	 
 return xmin, xmax
 
@@ -1665,11 +1634,10 @@
 	self.viewLim.intervaly = (ymin, ymax)
 if emit:
 	 self.callbacks.process('ylim_changed', self)
-	 # MGDTODO: It would be nice to do this is in the above callback list,
-	 # but it's difficult to tell how to initialize this at the
-	 # right time
-	 if self._sharey:
-		self._sharey.set_ylim(*self.viewLim.intervaly)
+	 # Call all of the other y-axes that are shared with this one
+	 for other in self._shared_y_axes.get_siblings(self):
+		if other is not self:
+		 other.set_ylim(self.viewLim.ymin, self.viewLim.ymax, emit=False)
 	 
 return ymin, ymax
 
Modified: branches/transforms/lib/matplotlib/axis.py
===================================================================
--- branches/transforms/lib/matplotlib/axis.py	2007年09月18日 16:21:37 UTC (rev 3855)
+++ branches/transforms/lib/matplotlib/axis.py	2007年09月18日 19:29:21 UTC (rev 3856)
@@ -1033,8 +1033,7 @@
 bbox = Bbox.union(bboxes)
 bottom = bbox.ymin
 
- self.label.set_position( (x, bottom-self.LABELPAD*self.figure.dpi/72.0))
-# self.label.set_position( (x, bottom-self.LABELPAD*self.figure.dpi.get()/72.0)) MGDTODO
+ self.label.set_position( (x, bottom-self.LABELPAD*self.figure.dpi / 72.0))
 
 else:
 if not len(bboxes2):
@@ -1057,7 +1056,6 @@
 bbox = Bbox.union(bboxes)
 bottom = bbox.ymin
 self.offsetText.set_position((x, bottom-self.OFFSETTEXTPAD*self.figure.dpi/72.0))
-# self.offsetText.set_position((x, bottom-self.OFFSETTEXTPAD*self.figure.dpi.get()/72.0)) MGDTODO
 	
 def set_ticks_position(self, position):
 """
@@ -1225,7 +1223,6 @@
 left = bbox.xmin
 
 self.label.set_position( (left-self.LABELPAD*self.figure.dpi/72.0, y))
-	 # self.label.set_position( (left-self.LABELPAD*self.figure.dpi.get()/72.0, y)) MGDTODO
 	 
 else:
 if not len(bboxes2):
@@ -1245,7 +1242,6 @@
 x,y = self.offsetText.get_position()
 top = self.axes.bbox.ymax
 self.offsetText.set_position((x, top+self.OFFSETTEXTPAD*self.figure.dpi/72.0))
-# self.offsetText.set_position((x, top+self.OFFSETTEXTPAD*self.figure.dpi.get()/72.0)) MGDTODO
 	
 def set_offset_position(self, position):
 assert position == 'left' or position == 'right'
Modified: branches/transforms/lib/matplotlib/backend_bases.py
===================================================================
--- branches/transforms/lib/matplotlib/backend_bases.py	2007年09月18日 16:21:37 UTC (rev 3855)
+++ branches/transforms/lib/matplotlib/backend_bases.py	2007年09月18日 19:29:21 UTC (rev 3856)
@@ -18,8 +18,9 @@
 """An abstract base class to handle drawing/rendering operations
 """
 # This will cache paths across rendering instances
- # Each subclass of RenderBase should define this -->
- # _paths = weakref.WeakKeyDictionary()
+ # Each subclass of RenderBase should define this a weak-keyed
+ # dictionary to hold native paths
+ # _native_paths = weakref.WeakKeyDictionary()
 
 def __init__(self):
 self._texmanager = None
@@ -44,7 +45,7 @@
 	 self._native_paths[path] = native_path
 	return native_path
 
- def draw_path(self, gc, path, transform, rgbFace = None):
+ def draw_path(self, gc, path, transform, rgbFace=None):
 	"""
 	Handles the caching of the native path associated with the
 	given path and calls the underlying backend's _draw_path to
@@ -67,17 +68,31 @@
 	passed to them in draw_path.
 	"""
 	return path
+
+ def draw_markers(self, gc, marker_path, marker_trans, path, trans, rgbFace=None):
+	native_marker_path = self._get_cached_native_path(marker_path)
+	self._draw_native_markers(gc, native_marker_path, marker_trans, path, trans, rgbFace)
 	
- def draw_arc(self, gc, rgbFace, x, y, width, height, angle1, angle2,
- rotation):
+ def _draw_native_markers(self, gc, native_marker_path, marker_trans, path, trans, rgbFace=None):
 """
- Draw an arc using GraphicsContext instance gcEdge, centered at x,y,
- with width and height and angles from 0.0 to 360.0
- 0 degrees is at 3-o'clock
- positive angles are anti-clockwise
- draw rotated 'rotation' degrees anti-clockwise about x,y
+ This method is currently underscore hidden because the
+ draw_markers method is being used as a sentinel for newstyle
+ backend drawing
 
- If the color rgbFace is not None, fill the arc with it.
+ path - a matplotlib.agg.path_storage instance
+
+ Draw the marker specified in path with graphics context gc at
+ each of the locations in arrays x and y. trans is a
+ matplotlib.transforms.Transformation instance used to
+ transform x and y to display coords. It consists of an
+ optional nonlinear component and an affine. You can access
+ these two components as
+
+ if transform.need_nonlinear():
+ x,y = transform.nonlinear_only_numerix(x, y)
+ # the a,b,c,d,tx,ty affine which transforms x and y
+ vec6 = transform.as_vec6_val()
+ ...backend dependent affine...
 """
 raise NotImplementedError
 
@@ -109,30 +124,21 @@
 """
 return False
 
- def draw_markers(self, gc, marker_path, marker_trans, path, trans, rgbFace=None):
-	native_marker_path = self._get_cached_native_path(marker_path)
-	self._draw_native_markers(gc, native_marker_path, marker_trans, path, trans, rgbFace)
-	
- def _draw_native_markers(self, gc, native_marker_path, marker_trans, path, trans, rgbFace=None):
+ ######################################################################
+ ## OLD API IS BELOW
+ ## These functions no longer need to be implemented in the backends --
+ ## they now perform all of their functions in terms of the new API.
+ 
+ def draw_arc(self, gc, rgbFace, x, y, width, height, angle1, angle2,
+ rotation):
 """
- This method is currently underscore hidden because the
- draw_markers method is being used as a sentinel for newstyle
- backend drawing
+ Draw an arc using GraphicsContext instance gcEdge, centered at x,y,
+ with width and height and angles from 0.0 to 360.0
+ 0 degrees is at 3-o'clock
+ positive angles are anti-clockwise
+ draw rotated 'rotation' degrees anti-clockwise about x,y
 
- path - a matplotlib.agg.path_storage instance
-
- Draw the marker specified in path with graphics context gc at
- each of the locations in arrays x and y. trans is a
- matplotlib.transforms.Transformation instance used to
- transform x and y to display coords. It consists of an
- optional nonlinear component and an affine. You can access
- these two components as
-
- if transform.need_nonlinear():
- x,y = transform.nonlinear_only_numerix(x, y)
- # the a,b,c,d,tx,ty affine which transforms x and y
- vec6 = transform.as_vec6_val()
- ...backend dependent affine...
+ If the color rgbFace is not None, fill the arc with it.
 """
 raise NotImplementedError
 
@@ -346,8 +352,10 @@
 
 If rgbFace is not None, fill the rectangle with it.
 """
- raise NotImplementedError
-
+	warnings.warn("draw_rectangle called", warnings.PendingDeprecationWarning)
+	transform = transforms.Affine2D().scale(width, height).translate(x, y)
+	self.draw_path(gcEdge, Path.unit_rectangle(), transform, rgbFace)
+	
 def draw_regpoly_collection(
 self, clipbox, offsets, transOffset, verts, sizes,
 facecolors, edgecolors, linewidths, antialiaseds):
@@ -1221,8 +1229,6 @@
 origfacecolor = self.figure.get_facecolor()
 origedgecolor = self.figure.get_edgecolor()
 
-	# MGDTODO
- # self.figure.dpi.set(dpi)
 self.figure.dpi = dpi
 self.figure.set_facecolor(facecolor)
 self.figure.set_edgecolor(edgecolor)
@@ -1236,12 +1242,12 @@
 orientation=orientation,
 **kwargs)
 finally:
-	 # MGDTODO
- # self.figure.dpi.set(origDPI)
 self.figure.dpi = origDPI
 self.figure.set_facecolor(origfacecolor)
 self.figure.set_edgecolor(origedgecolor)
 self.figure.set_canvas(self)
+
+ self.draw()
 
 return result
 
@@ -1623,8 +1629,8 @@
 lims.append( (xmin, xmax, ymin, ymax) )
 # Store both the original and modified positions
 pos.append( (
-		 a.get_position(True),
- a.get_position() ) )
+		 copy.copy(a.get_position(True)),
+ copy.copy(a.get_position() )) )
 self._views.push(lims)
 self._positions.push(pos)
 self.set_history_buttons()
Modified: branches/transforms/lib/matplotlib/backends/backend_agg.py
===================================================================
--- branches/transforms/lib/matplotlib/backends/backend_agg.py	2007年09月18日 16:21:37 UTC (rev 3855)
+++ branches/transforms/lib/matplotlib/backends/backend_agg.py	2007年09月18日 19:29:21 UTC (rev 3856)
@@ -114,9 +114,6 @@
 self.height = height
 if __debug__: verbose.report('RendererAgg.__init__ width=%s, \
 height=%s'%(width, height), 'debug-annoying')
-	# MGDTODO
-# self._renderer = _RendererAgg(int(width), int(height), dpi.get(),
-# 				 debug=False)
 self._renderer = _RendererAgg(int(width), int(height), dpi,
 				 debug=False)
 if __debug__: verbose.report('RendererAgg.__init__ _RendererAgg done',
@@ -136,35 +133,6 @@
 def _draw_native_path(self, gc, path, transform, rgbFace):
 	return self._renderer.draw_path(gc, path, transform.get_matrix(), rgbFace)
 
- def draw_arc(self, gcEdge, rgbFace, x, y, width, height, angle1, angle2, rotation):
- """
- Draw an arc centered at x,y with width and height and angles
- from 0.0 to 360.0
-
- If rgbFace is not None, fill the rectangle with that color. gcEdge
- is a GraphicsContext instance
-
- Currently, I'm only supporting ellipses, ie angle args are
- ignored
- """
- if __debug__: verbose.report('RendererAgg.draw_arc', 'debug-annoying')
- self._renderer.draw_ellipse(
- gcEdge, rgbFace, x, y, width/2, height/2, rotation) # ellipse takes radius
-
-
- def draw_line(self, gc, x1, y1, x2, y2):
- """
- x and y are equal length arrays, draw lines connecting each
- point in x, y
- """
- if __debug__: verbose.report('RendererAgg.draw_line', 'debug-annoying')
- x = npy.array([x1,x2], float)
- y = npy.array([y1,y2], float)
- self._renderer.draw_lines(gc, x, y)
-
- def draw_lines(self, gc, x, y, transform):
-	return self._renderer.draw_lines(gc, x, y, transform.to_values())
-
 def _draw_native_markers(self, gc, native_marker_path, marker_trans, path, trans, rgbFace=None):
 	return self._renderer.draw_markers(
 	 gc,
@@ -172,18 +140,6 @@
 	 path.vertices, path.codes, trans.get_matrix(),
 	 rgbFace)
 
- def draw_polygon(self, *args):
-	return self._renderer.draw_polygon(*args)
- 
- def draw_point(self, gc, x, y):
- """
- Draw a single point at x,y
- """
- if __debug__: verbose.report('RendererAgg.draw_point', 'debug-annoying')
- rgbFace = gc.get_rgb()
- self._renderer.draw_ellipse(
- gc, rgbFace, x, y, 0.5, 0.5, 0.0)
-
 def draw_mathtext(self, gc, x, y, s, prop, angle):
 """
 Draw the math text using matplotlib.mathtext
@@ -192,8 +148,6 @@
 'debug-annoying')
 ox, oy, width, height, descent, font_image, used_characters = \
 self.mathtext_parser.parse(s, self.dpi, prop)
-# ox, oy, width, height, descent, font_image, used_characters = \
-# self.mathtext_parser.parse(s, self.dpi.get(), prop) MGDTODO
 
 x = int(x) + ox
 y = int(y) - oy
@@ -227,7 +181,6 @@
 # (in vector space) in the above call to font.set_text.
 self._renderer.draw_text_image(font.get_image(), int(x), int(y) + 1, angle, gc)
 
-
 def get_text_width_height_descent(self, s, prop, ismath, rgb=(0,0,0)):
 """
 get the width and height in display coords of the string s
@@ -241,7 +194,7 @@
 # todo: handle props
 size = prop.get_size_in_points()
 texmanager = self.get_texmanager()
- Z = texmanager.get_rgba(s, size, self.dpi.get(), rgb)
+ Z = texmanager.get_rgba(s, size, self.dpi, rgb)
 m,n,tmp = Z.shape
 # TODO: descent of TeX text (I am imitating backend_ps here -JKS)
 return n, m, 0
@@ -249,8 +202,6 @@
 if ismath:
 ox, oy, width, height, descent, fonts, used_characters = \
 self.mathtext_parser.parse(s, self.dpi, prop)
-# ox, oy, width, height, descent, fonts, used_characters = \
-# self.mathtext_parser.parse(s, self.dpi.get(), prop) MGDTODO
 return width, height, descent
 font = self._get_agg_font(prop)
 font.set_text(s, 0.0, flags=LOAD_DEFAULT) # the width and height of unrotated string
@@ -265,7 +216,7 @@
 # todo, handle props, angle, origins
 rgb = gc.get_rgb()
 size = prop.get_size_in_points()
- dpi = self.dpi.get()
+ dpi = self.dpi
 
 flip = angle==90
 w,h,d = self.get_text_width_height_descent(s, prop, 'TeX', rgb)
@@ -306,7 +257,6 @@
 'return the canvas width and height in display coords'
 return self.width, self.height
 
-
 def _get_agg_font(self, prop):
 """
 Get the font for text instance t, cacheing for efficiency
@@ -325,11 +275,9 @@
 font.clear()
 size = prop.get_size_in_points()
 font.set_size(size, self.dpi)
- # font.set_size(size, self.dpi.get()) MGDTODO
 
 return font
 
-
 def points_to_pixels(self, points):
 """
 convert point measures to pixes using dpi and the pixels per
@@ -337,8 +285,6 @@
 """
 if __debug__: verbose.report('RendererAgg.points_to_pixels',
 'debug-annoying')
-	# MGDTODO
- # return points*self.dpi.get()/72.0
 return points*self.dpi/72.0
 
 def tostring_rgb(self):
@@ -404,9 +350,7 @@
 self.figure.draw(self.renderer)
 
 def get_renderer(self):
- l,b,w,h = self.figure.bbox.bounds
-	# MGDTODO
- # key = w, h, self.figure.dpi.get()
+ l, b, w, h = self.figure.bbox.bounds
 key = w, h, self.figure.dpi
 try: self._lastKey, self.renderer
 except AttributeError: need_new_renderer = True
Modified: branches/transforms/lib/matplotlib/backends/backend_gtkagg.py
===================================================================
--- branches/transforms/lib/matplotlib/backends/backend_gtkagg.py	2007年09月18日 16:21:37 UTC (rev 3855)
+++ branches/transforms/lib/matplotlib/backends/backend_gtkagg.py	2007年09月18日 19:29:21 UTC (rev 3856)
@@ -60,7 +60,6 @@
 w,h = widget.window.get_size()
 if w==1 or h==1: return # empty fig
 
-	# dpival = self.figure.dpi.get() MGDTODO
 # compute desired figure size in inches
 dpival = self.figure.dpi
 winch = w/dpival
Modified: branches/transforms/lib/matplotlib/backends/backend_tkagg.py
===================================================================
--- branches/transforms/lib/matplotlib/backends/backend_tkagg.py	2007年09月18日 16:21:37 UTC (rev 3855)
+++ branches/transforms/lib/matplotlib/backends/backend_tkagg.py	2007年09月18日 19:29:21 UTC (rev 3856)
@@ -175,7 +175,6 @@
 self._resize_callback(event)
 
 # compute desired figure size in inches
-	# dpival = self.figure.dpi.get() MGDTODO
 	dpival = self.figure.dpi
 winch = width/dpival
 hinch = height/dpival
Modified: branches/transforms/lib/matplotlib/cbook.py
===================================================================
--- branches/transforms/lib/matplotlib/cbook.py	2007年09月18日 16:21:37 UTC (rev 3855)
+++ branches/transforms/lib/matplotlib/cbook.py	2007年09月18日 19:29:21 UTC (rev 3856)
@@ -955,6 +955,84 @@
 outstream.write("Examining: %r\n" % (obj,))
 recurse(obj, obj, { }, [])
 
+class Grouper(object):
+ """
+ This class provides a lightweight way to group arbitrary objects
+ together into disjoint sets when a full-blown graph data structure
+ would be overkill.
+
+ Objects can be joined using .join(), tested for connectedness
+ using .joined(), and all disjoint sets can be retreived using
+ .get().
+
+ The objects being joined must be hashable.
+ 
+ For example:
+ 
+ >>> g = grouper.Grouper()
+ >>> g.join('a', 'b')
+ >>> g.join('b', 'c')
+ >>> g.join('d', 'e')
+ >>> list(g.get())
+ [['a', 'b', 'c'], ['d', 'e']]
+ >>> g.joined('a', 'b')
+ True
+ >>> g.joined('a', 'c')
+ True
+ >>> g.joined('a', 'd')
+ False""" 
+ def __init__(self, init=[]):
+	mapping = self._mapping = {}
+	for x in init:
+	 mapping[x] = [x]
+ 
+ def join(self, a, *args):
+	"""
+	Join given arguments into the same set.
+	Accepts one or more arguments.
+	"""
+	mapping = self._mapping
+	set_a = mapping.setdefault(a, [a])
+
+	for arg in args:
+	 set_b = mapping.get(arg)
+	 if set_b is None:
+		set_a.append(arg)
+		mapping[arg] = set_a
+	 elif set_b is not set_a:
+		if len(set_b) > len(set_a):
+		 set_a, set_b = set_b, set_a
+		set_a.extend(set_b)
+		for elem in set_b:
+		 mapping[elem] = set_a
+
+ def joined(self, a, b):
+	"""
+	Returns True if a and b are members of the same set.
+	"""
+	mapping = self._mapping
+	try:
+	 return mapping[a] is mapping[b]
+	except KeyError:
+	 return False
+
+ def __iter__(self):
+	"""
+	Returns an iterator returning each of the disjoint sets as a list.
+	"""
+	seen = set()
+	for elem, group in self._mapping.iteritems():
+	 if elem not in seen:
+		yield group
+		seen.update(group)
+
+ def get_siblings(self, a):
+	"""
+	Returns all of the items joined with the given item, including
+	itself.
+	"""
+	return self._mapping.get(a, [a])
+		
 if __name__=='__main__':
 assert( allequal([1,1,1]) )
 assert(not allequal([1,1,0]) )
Modified: branches/transforms/lib/matplotlib/figure.py
===================================================================
--- branches/transforms/lib/matplotlib/figure.py	2007年09月18日 16:21:37 UTC (rev 3855)
+++ branches/transforms/lib/matplotlib/figure.py	2007年09月18日 19:29:21 UTC (rev 3856)
@@ -161,10 +161,8 @@
 def _get_dpi(self):
 	return self._dpi
 def _set_dpi(self, dpi):
-	print "setting dpi"
 	self._dpi = dpi
 	self._dpi_scale_trans.clear().scale(dpi, dpi)
-	print self._dpi_scale_trans
 dpi = property(_get_dpi, _set_dpi)
 	
 def autofmt_xdate(self, bottom=0.2, rotation=30, ha='right'):
@@ -178,10 +176,7 @@
 bottom : the bottom of the subplots for subplots_adjust
 rotation: the rotation of the xtick labels
 ha : the horizontal alignment of the xticklabels
-
-
 """
-
 for ax in self.get_axes():
 if not hasattr(ax, 'is_last_row'):
 raise RuntimeError('Axes must be subplot instances; found %s'%type(ax))
@@ -333,11 +328,8 @@
 
 	dpival = self.dpi
 	self.bbox_inches.max = w, h
- # self.figwidth.set(w) MGDTODO
- # self.figheight.set(h)
 	
 if forward:
- # dpival = self.dpi.get()
 dpival = self.dpi
 canvasw = w*dpival
 canvash = h*dpival
@@ -347,7 +339,6 @@
 
 def get_size_inches(self):
 return self.bbox_inches.max
- # return self.figwidth.get(), self.figheight.get() MGDTODO
 
 def get_edgecolor(self):
 'Get the edge color of the Figure rectangle'
@@ -360,7 +351,6 @@
 def get_figwidth(self):
 'Return the figwidth as a float'
 	return self.bbox_inches.xmax
- # return self.figwidth.get() MGDTODO
 
 def get_figheight(self):
 'Return the figheight as a float'
@@ -369,7 +359,6 @@
 def get_dpi(self):
 'Return the dpi as a float'
 return self.dpi
- # return self.dpi.get() MGDTODO
 
 def get_frameon(self):
 'get the boolean indicating frameon'
@@ -397,7 +386,6 @@
 
 ACCEPTS: float
 """
- # self.dpi.set(val) MGDTODO
 	self.dpi = val
 
 def set_figwidth(self, val):
@@ -406,7 +394,6 @@
 
 ACCEPTS: float
 """
- # self.figwidth.set(val) MGDTODO
 	self.bbox_inches.xmax = val
 	
 def set_figheight(self, val):
@@ -415,7 +402,6 @@
 
 ACCEPTS: float
 """
-	# MGDTODO (set())
 	self.bbox_inches.ymax = val
 
 def set_frameon(self, b):
@@ -598,8 +584,6 @@
 #print 'figure draw'
 if not self.get_visible(): return
 renderer.open_group('figure')
-	# MGDTODO
- # self.transFigure.freeze() # eval the lazy objects
 
 if self.frameon: self.figurePatch.draw(renderer)
 
@@ -633,8 +617,6 @@
 for legend in self.legends:
 legend.draw(renderer)
 
-	# MGDTODO
-	# self.transFigure.thaw() # release the lazy objects
 renderer.close_group('figure')
 
 self._cachedRenderer = renderer
Modified: branches/transforms/lib/matplotlib/legend.py
===================================================================
--- branches/transforms/lib/matplotlib/legend.py	2007年09月18日 16:21:37 UTC (rev 3855)
+++ branches/transforms/lib/matplotlib/legend.py	2007年09月18日 19:29:21 UTC (rev 3856)
@@ -21,7 +21,7 @@
 up the legend
 """
 from __future__ import division
-import sys, warnings
+import copy, sys, warnings
 
 import numpy as npy
 
@@ -558,9 +558,7 @@
 handle.set_height(h/2)
 
 # Set the data for the legend patch
-	# MGDTODO: This copy may no longer be needed now that Bboxes are
-	# essentially immutable
- bbox = self._get_handle_text_bbox(renderer).copy()
+ bbox = copy.copy(self._get_handle_text_bbox(renderer))
 
 bbox = bbox.scaled(1 + self.pad, 1 + self.pad)
 l,b,w,h = bbox.get_bounds()
Modified: branches/transforms/lib/matplotlib/lines.py
===================================================================
--- branches/transforms/lib/matplotlib/lines.py	2007年09月18日 16:21:37 UTC (rev 3855)
+++ branches/transforms/lib/matplotlib/lines.py	2007年09月18日 19:29:21 UTC (rev 3856)
@@ -352,32 +352,18 @@
 self._picker = p
 
 def get_window_extent(self, renderer):
- self._newstyle = hasattr(renderer, 'draw_markers')
- if self._newstyle:
- x = self._x
- y = self._y
- else:
- x, y = self._get_plottable()
+ xys = self.get_transform()(self._xys)
 
-	# MGDTODO: Put this in a single Nx2 array, rather than these
-	# separate ones
-	#### Conversion code
-	a = npy.vstack((x, y)).swapaxes(0, 1)
-	####
- x, y = self.get_transform()(a)
-	print "get_window_extent", self.get_transform()
-	
- #x, y = self.get_transform().seq_x_y(x, y)
+	x = xys[:, 0]
+	y = xys[:, 1]
+ left = x.min()
+ bottom = y.min()
+ width = x.max() - left
+ height = y.max() - bottom
 
- left = min(x)
- bottom = min(y)
- width = max(x) - left
- height = max(y) - bottom
-
 # correct for marker size, if any
 if self._marker is not None:
- ms = self._markersize/72.0*self.figure.dpi
- # ms = self._markersize/72.0*self.figure.dpi.get() MGDTODO
+ ms = self._markersize / 72.0 * self.figure.dpi
 left -= ms/2
 bottom -= ms/2
 width += ms
@@ -411,6 +397,7 @@
 def recache(self):
 #if self.axes is None: print 'recache no axes'
 #else: print 'recache units', self.axes.xaxis.units, self.axes.yaxis.units
+	# MGDTODO: Deal with units
 x = ma.asarray(self.convert_xunits(self._xorig), float)
 y = ma.asarray(self.convert_yunits(self._yorig), float)
 
@@ -435,15 +422,15 @@
 else:
 self._segments = None
 
- self._x = npy.asarray(x, float)
- self._y = npy.asarray(y, float)
-	self._path = Path(npy.vstack((self._x, self._y)).transpose(),
-			 closed=False)
+	self._xy = npy.vstack((npy.asarray(x, npy.float_),
+			 npy.asarray(y, npy.float_))).transpose()
+	self._x = self._xy[:, 0]
+	self._y = self._xy[:, 1]
+	self._path = Path(self._xy, closed=False)
 	
 self._logcache = None
 
 
-
 def _is_sorted(self, x):
 "return true if x is sorted"
 if len(x)<2: return 1
Modified: branches/transforms/lib/matplotlib/transforms.py
===================================================================
--- branches/transforms/lib/matplotlib/transforms.py	2007年09月18日 16:21:37 UTC (rev 3855)
+++ branches/transforms/lib/matplotlib/transforms.py	2007年09月18日 19:29:21 UTC (rev 3856)
@@ -19,9 +19,9 @@
 self._parents = Set()
 
 def invalidate(self):
- if not self._do_invalidation():
- for parent in self._parents:
- parent.invalidate()
+ self._do_invalidation()
+ for parent in self._parents:
+ parent.invalidate()
 
 def _do_invalidation(self):
 return False
@@ -187,14 +187,16 @@
 return 'Bbox(%s)' % repr(self._points)
 __str__ = __repr__
 
- # JDH: the update method will update the box limits from the
- # existing limits and the new data; it appears here you are just
- # using the new data. We use an "ignore" flag to specify whether
- # you want to include the existing data or not in the update
 def update_from_data(self, x, y, ignore=True):
- self._points = npy.array(
- [[x.min(), y.min()], [x.max(), y.max()]],
- npy.float_)
+	if ignore:
+	 self._points = npy.array(
+		[[x.min(), y.min()], [x.max(), y.max()]],
+		npy.float_)
+	else:
+	 self._points = npy.array(
+		[[min(x.min(), self.xmin), min(y.min(), self.ymin)],
+		 [max(x.max(), self.xmax), max(y.max(), self.ymax)]],
+		 npy.float_)
 self.invalidate()
 
 # MGDTODO: Probably a more efficient ways to do this...
@@ -409,9 +411,7 @@
 	return self.get_matrix()
 	
 def _do_invalidation(self):
- result = self._inverted is None
 self._inverted = None
- return result
 
 #@staticmethod
 def _concat(a, b):
@@ -494,6 +494,7 @@
 if matrix is None:
 matrix = npy.identity(3)
 else:
+	 matrix = npy.asarray(matrix, npy.float_)
 assert matrix.shape == (3, 3)
 self._mtx = matrix
 self._inverted = None
@@ -629,8 +630,6 @@
 if self._mtx is not None:
 self._mtx = None
 Affine2DBase._do_invalidation(self)
- return False
- return True
 
 def is_separable(self):
 return True
@@ -684,7 +683,7 @@
 
 def _do_invalidation(self):
 self._mtx = None
- Affine2DBase._do_invalidation(self)
+ return Affine2DBase._do_invalidation(self)
 
 def get_matrix(self):
 if self._mtx is None:
@@ -718,8 +717,6 @@
 if self._mtx is not None:
 self._mtx = None
 Affine2DBase._do_invalidation(self)
- return False
- return True
 
 def is_separable(self):
 return True
Modified: branches/transforms/src/_backend_agg.cpp
===================================================================
--- branches/transforms/src/_backend_agg.cpp	2007年09月18日 16:21:37 UTC (rev 3855)
+++ branches/transforms/src/_backend_agg.cpp	2007年09月18日 19:29:21 UTC (rev 3856)
@@ -456,7 +456,7 @@
 //return the agg::rect for bbox, flipping y
 PyArrayObject *bbox = (PyArrayObject *) PyArray_ContiguousFromObject(o.ptr(), PyArray_DOUBLE, 2, 2);
 
- if (!bbox || bbox->nd != 2 bbox->dimensions[0] != 2 || bbox->dimensions[1] != 2)
+ if (!bbox || bbox->nd != 2 || bbox->dimensions[0] != 2 || bbox->dimensions[1] != 2)
 throw Py::TypeError
 ("Expected a Bbox object.");
 
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
From: <md...@us...> - 2007年09月19日 16:18:56
Revision: 3858
 http://matplotlib.svn.sourceforge.net/matplotlib/?rev=3858&view=rev
Author: mdboom
Date: 2007年09月19日 09:18:51 -0700 (2007年9月19日)
Log Message:
-----------
Got steps_demo.py working
Modified Paths:
--------------
 branches/transforms/lib/matplotlib/backend_bases.py
 branches/transforms/lib/matplotlib/lines.py
 branches/transforms/lib/matplotlib/path.py
 branches/transforms/lib/matplotlib/transforms.py
 branches/transforms/src/_backend_agg.cpp
 branches/transforms/src/_backend_agg.h
Modified: branches/transforms/lib/matplotlib/backend_bases.py
===================================================================
--- branches/transforms/lib/matplotlib/backend_bases.py	2007年09月19日 13:28:11 UTC (rev 3857)
+++ branches/transforms/lib/matplotlib/backend_bases.py	2007年09月19日 16:18:51 UTC (rev 3858)
@@ -40,7 +40,7 @@
 def _get_cached_native_path(self, path):
 	native_path = self._native_paths.get(path)
 	if native_path is None:
-	 # print "CACHE MISS", path
+	 print "CACHE MISS", path
 	 native_path = self.convert_to_native_path(path)
 	 self._native_paths[path] = native_path
 	return native_path
Modified: branches/transforms/lib/matplotlib/lines.py
===================================================================
--- branches/transforms/lib/matplotlib/lines.py	2007年09月19日 13:28:11 UTC (rev 3857)
+++ branches/transforms/lib/matplotlib/lines.py	2007年09月19日 16:18:51 UTC (rev 3858)
@@ -25,53 +25,6 @@
 (TICKLEFT, TICKRIGHT, TICKUP, TICKDOWN,
 CARETLEFT, CARETRIGHT, CARETUP, CARETDOWN) = range(8)
 
-def unmasked_index_ranges(mask, compressed = True):
- '''
- Calculate the good data ranges in a masked 1-D npy.array, based on mask.
-
- Returns Nx2 npy.array with each row the start and stop indices
- for slices of the compressed npy.array corresponding to each of N
- uninterrupted runs of unmasked values.
- If optional argument compressed is False, it returns the
- start and stop indices into the original npy.array, not the
- compressed npy.array.
- Returns None if there are no unmasked values.
-
- Example:
-
- y = ma.array(npy.arange(5), mask = [0,0,1,0,0])
- #ii = unmasked_index_ranges(y.mask())
- ii = unmasked_index_ranges(ma.getmask(y))
- # returns [[0,2,] [2,4,]]
-
- y.compressed().filled()[ii[1,0]:ii[1,1]]
- # returns npy.array [3,4,]
- # (The 'filled()' method converts the masked npy.array to a numerix npy.array.)
-
- #i0, i1 = unmasked_index_ranges(y.mask(), compressed=False)
- i0, i1 = unmasked_index_ranges(ma.getmask(y), compressed=False)
- # returns [[0,3,] [2,5,]]
-
- y.filled()[ii[1,0]:ii[1,1]]
- # returns npy.array [3,4,]
-
- '''
- m = npy.concatenate(((1,), mask, (1,)))
- indices = npy.arange(len(mask) + 1)
- mdif = m[1:] - m[:-1]
- i0 = npy.compress(mdif == -1, indices)
- i1 = npy.compress(mdif == 1, indices)
- assert len(i0) == len(i1)
- if len(i1) == 0:
- return None
- if not compressed:
- return npy.concatenate((i0[:, npy.newaxis], i1[:, npy.newaxis]), axis=1)
- seglengths = i1 - i0
- breakpoints = npy.cumsum(seglengths)
- ic0 = npy.concatenate(((0,), breakpoints[:-1]))
- ic1 = breakpoints
- return npy.concatenate((ic0[:, npy.newaxis], ic1[:, npy.newaxis]), axis=1)
-
 def segment_hits(cx,cy,x,y,radius):
 """Determine if any line segments are within radius of a point. Returns
 the list of line segments that are within that radius.
@@ -117,7 +70,7 @@
 '--' : '_draw_dashed',
 '-.' : '_draw_dash_dot',
 ':' : '_draw_dotted',
- 'steps': '_draw_solid',
+ 'steps': '_draw_steps',
 'None' : '_draw_nothing',
 ' ' : '_draw_nothing',
 '' : '_draw_nothing',
@@ -394,6 +347,8 @@
 self._yorig = y
 self.recache()
 
+ _masked_array_to_path_code_mapping = npy.array(
+ [Path.LINETO, Path.IGNORE, Path.MOVETO], Path.code_type)
 def recache(self):
 #if self.axes is None: print 'recache no axes'
 #else: print 'recache units', self.axes.xaxis.units, self.axes.yaxis.units
@@ -411,36 +366,28 @@
 if len(x) != len(y):
 raise RuntimeError('xdata and ydata must be the same length')
 
-	# MGDTODO: Deal with segments
+	self._xy = npy.vstack((npy.asarray(x, npy.float_),
+			 npy.asarray(y, npy.float_))).transpose()
+	self._x = self._xy[:, 0] # just a view
+	self._y = self._xy[:, 1] # just a view
+ self._logcache = None
+
 mx = ma.getmask(x)
 my = ma.getmask(y)
 mask = ma.mask_or(mx, my)
+ codes = None
 if mask is not ma.nomask:
- x = ma.masked_array(x, mask=mask).compressed()
- y = ma.masked_array(y, mask=mask).compressed()
- self._segments = unmasked_index_ranges(mask)
- else:
- self._segments = None
-
-	self._xy = npy.vstack((npy.asarray(x, npy.float_),
-			 npy.asarray(y, npy.float_))).transpose()
-	self._x = self._xy[:, 0]
-	self._y = self._xy[:, 1]
- self._logcache = None
+ m = npy.concatenate(((1,), mask, (1,)))
+ mdif = m[1:] - m[:-1]
+ mdif = npy.maximum((mdif[:-1] * -2), mask)
+ codes = npy.take(
+ self._masked_array_to_path_code_mapping,
+ mdif)
+ self._path = Path(self._xy, codes, closed=False)
+ # MGDTODO: If _draw_steps is removed, remove the following line also
+ self._step_path = None
 
- if self._linestyle == 'steps':
- siz=len(xt)
- if siz<2: return
- xt, yt = self._x, self._y
- xt2=npy.ones((2*siz,), xt.dtype)
- xt2[0:-1:2], xt2[1:-1:2], xt2[-1] = xt, xt[1:], xt[-1]
- yt2=npy.ones((2*siz,), yt.dtype)
- yt2[0:-1:2], yt2[1::2] = yt, yt
- self._path = Path(npy.vstack((xt2, yt2)).transpose(), closed=False)
- else:
- self._path = Path(self._xy, closed=False)
 
-
 def _is_sorted(self, x):
 "return true if x is sorted"
 if len(x)<2: return 1
@@ -507,14 +454,7 @@
 
 funcname = self._lineStyles.get(self._linestyle, '_draw_nothing')
 lineFunc = getattr(self, funcname)
-
-	# MGDTODO: Deal with self._segments
- if self._segments is not None:
- for ii in self._segments:
- lineFunc(renderer, gc, xt[ii[0]:ii[1]], yt[ii[0]:ii[1]])
-
- else:
- lineFunc(renderer, gc, self._path)
+ lineFunc(renderer, gc, self._path)
 	 
 	# MGDTODO: Deal with markers
 if self._marker is not None:
@@ -709,7 +649,29 @@
 def _draw_nothing(self, renderer, gc, path):
 pass
 
- 
+
+ def _draw_steps(self, renderer, gc, path):
+ # We generate the step function path on-the-fly, and then cache it.
+ # The cache may be later invalidated when the data changes
+ # (in self.recache())
+
+ # MGDTODO: Untested -- using pylab.step doesn't actually trigger
+ # this code -- the path is "stepped" before even getting to this
+ # class. Perhaps this should be removed here, since it is not as
+ # powerful as what is in axes.step() anyway.
+ if self._step_path is None:
+ vertices = self._path.vertices
+ codes = self._path.codes
+ siz = len(vertices)
+ if siz<2: return
+ new_vertices = npy.zeros((2*siz, 2), vertices.dtype)
+ new_vertices[0:-1:2, 0], new_vertices[1:-1:2, 0], newvertices[-1, 0] = vertices[:, 0], vertices[1:, 0], vertices[-1, 0]
+ new_vertices[0:-1:2, 1], new_vertices[1::2, 1] = vertices[:, 1], vertices[:, 1]
+ self._step_path = Path(new_vertices, closed=False)
+ gc.set_linestyle('solid')
+	renderer.draw_path(gc, self._step_path, self.get_transform())
+
+ 
 def _draw_solid(self, renderer, gc, path):
 gc.set_linestyle('solid')
 	renderer.draw_path(gc, path, self.get_transform())
Modified: branches/transforms/lib/matplotlib/path.py
===================================================================
--- branches/transforms/lib/matplotlib/path.py	2007年09月19日 13:28:11 UTC (rev 3857)
+++ branches/transforms/lib/matplotlib/path.py	2007年09月19日 16:18:51 UTC (rev 3858)
@@ -1,10 +1,10 @@
 import numpy as npy
 
-VALIDATE_PATHS = True
+DEBUG = True
 
 class Path(object):
 # Path codes
- STOP = 0
+ IGNORE = 0 # 1 vertex
 MOVETO = 1 # 1 vertex
 LINETO = 2 # 1 vertex
 CURVE3 = 3 # 2 vertices
@@ -18,7 +18,7 @@
 UBSPLINE = 8
 ####
 
- NUM_VERTICES = [0, 1, 1, 2, 3, 0]
+ NUM_VERTICES = [1, 1, 1, 2, 3, 0]
 
 code_type = npy.uint8
 
@@ -43,7 +43,7 @@
 	 
 	assert self._codes.ndim == 1
 
-	if VALIDATE_PATHS:
+	if DEBUG:
 	 i = 0
 	 NUM_VERTICES = self.NUM_VERTICES
 	 for code in codes:
Modified: branches/transforms/lib/matplotlib/transforms.py
===================================================================
--- branches/transforms/lib/matplotlib/transforms.py	2007年09月19日 13:28:11 UTC (rev 3857)
+++ branches/transforms/lib/matplotlib/transforms.py	2007年09月19日 16:18:51 UTC (rev 3858)
@@ -32,18 +32,6 @@
 for child in children:
 getattr(self, child)._parents.add(self)
 self._children = children
-
- # MGDTODO: decide whether we need this in-place updating and
- # remove if not
-# def replace_child(self, index, child):
-# children = self._children
-# getattr(self, children[index])._parents.remove(self)
-# setattr(self, children[index], child)
-# # We have to reset children in case two or more
-# # of the children are the same
-# for child in children:
-# getattr(self, child)._parents.add(self)
-# self.invalidate()
 
 class BboxBase(TransformNode):
 '''
@@ -327,53 +315,7 @@
 if self._points is None:
 self._points = self.transform(self.bbox.get_points())
 return self._points
-
-# MGDTODO: This code probably works, but I don't think it's a good idea
-# (from a code clarity perspective)
-# class BlendedBbox(BboxBase):
-# def __init__(self, bbox_x, bbox_y):
-# assert isinstance(bbox_x, BboxBase)
-# assert isinstance(bbox_y, BboxBase)
-
-# BboxBase.__init__(self)
-# self._x = bbox_x
-# self._y = bbox_y
-# self.set_children(['_x', '_y'])
-# self._points = None
-
-# def __repr__(self):
-# return "TransformedBbox(%s, %s)" % (self.bbox, self.transform)
-# __str__ = __repr__
 
-# def _do_invalidation(self):
-# self._points = None
-
-# def get_points(self):
-# if self._points is None:
-# # MGDTODO: Optimize
-# if self._x == self._y:
-# self._points = self._x.get_points()
-# else:
-# x_points = self._x.get_points()
-# y_points = self._y.get_points()
-# self._points = npy.array(
-# [[x_points[0,0], y_points[0,1]],
-# [x_points[1,0], y_points[1,1]]],
-# npy.float_)
-# return self._points
-
-# def _set_intervalx(self, pair):
-# # MGDTODO: Optimize
-# bbox = Bbox([[pair[0], 0.0], [pair[1], 0.0]])
-# self.replace_child(0, bbox)
-# intervalx = property(BboxBase._get_intervalx, _set_intervalx)
-
-# def _set_intervaly(self, pair):
-# # MGDTODO: Optimize
-# bbox = Bbox([[0.0, pair[0]], [0.0, pair[1]]])
-# self.replace_child(1, bbox)
-# intervaly = property(BboxBase._get_intervaly, _set_intervaly)
- 
 class Transform(TransformNode):
 def __init__(self):
 TransformNode.__init__(self)
@@ -746,7 +688,6 @@
 self._mtx = affine._mtx
 return self._mtx
 
-# MGDTODO: There's probably a better place for this
 def nonsingular(vmin, vmax, expander=0.001, tiny=1e-15, increasing=True):
 '''
 Ensure the endpoints of a range are not too close together.
Modified: branches/transforms/src/_backend_agg.cpp
===================================================================
--- branches/transforms/src/_backend_agg.cpp	2007年09月19日 13:28:11 UTC (rev 3857)
+++ branches/transforms/src/_backend_agg.cpp	2007年09月19日 16:18:51 UTC (rev 3858)
@@ -634,6 +634,9 @@
 if (num_vertices) {
 	for (size_t j=0; j<num_vertices; ++j)
 	 GET_NEXT_VERTEX(x, y);
+	if (code_i == IGNORE)
+	 continue;
+
 	trans.transform(&x, &y);
 	
 	if (face.first) {
@@ -860,6 +863,10 @@
 
 for (size_t i = 0; i < N; ++i) {
 switch (*(unsigned char*)(code_i)) {
+ case IGNORE:
+	GET_NEXT_VERTEX(x0, y0);
+	_VERBOSE("IGNORE");
+	break;
 case MOVETO:
 	GET_NEXT_VERTEX(x0, y0);
 	move_to(x0, y0);
Modified: branches/transforms/src/_backend_agg.h
===================================================================
--- branches/transforms/src/_backend_agg.h	2007年09月19日 13:28:11 UTC (rev 3857)
+++ branches/transforms/src/_backend_agg.h	2007年09月19日 16:18:51 UTC (rev 3858)
@@ -40,14 +40,14 @@
 #include "agg_vcgen_markers_term.h"
 
 // These are copied directly from path.py, and must be kept in sync
-#define STOP 0
+#define IGNORE 0
 #define MOVETO 1
 #define LINETO 2
 #define CURVE3 3
 #define CURVE4 4
 #define CLOSEPOLY 5
 
-const size_t NUM_VERTICES[] = { 0, 1, 1, 2, 3, 0 };
+const size_t NUM_VERTICES[] = { 1, 1, 1, 2, 3, 0 };
 
 typedef agg::pixfmt_rgba32 pixfmt;
 typedef agg::renderer_base<pixfmt> renderer_base;
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
From: <md...@us...> - 2007年09月19日 19:48:22
Revision: 3860
 http://matplotlib.svn.sourceforge.net/matplotlib/?rev=3860&view=rev
Author: mdboom
Date: 2007年09月19日 12:48:17 -0700 (2007年9月19日)
Log Message:
-----------
Use iterator rather than caching approach for paths
Modified Paths:
--------------
 branches/transforms/lib/matplotlib/backends/backend_agg.py
 branches/transforms/src/_backend_agg.cpp
 branches/transforms/src/_backend_agg.h
Modified: branches/transforms/lib/matplotlib/backends/backend_agg.py
===================================================================
--- branches/transforms/lib/matplotlib/backends/backend_agg.py	2007年09月19日 19:46:34 UTC (rev 3859)
+++ branches/transforms/lib/matplotlib/backends/backend_agg.py	2007年09月19日 19:48:17 UTC (rev 3860)
@@ -112,8 +112,7 @@
 self.dpi = dpi
 self.width = width
 self.height = height
- if __debug__: verbose.report('RendererAgg.__init__ width=%s, \
- height=%s'%(width, height), 'debug-annoying')
+ if __debug__: verbose.report('RendererAgg.__init__ width=%s, height=%s'%(width, height), 'debug-annoying')
 self._renderer = _RendererAgg(int(width), int(height), dpi,
 				 debug=False)
 if __debug__: verbose.report('RendererAgg.__init__ _RendererAgg done',
Modified: branches/transforms/src/_backend_agg.cpp
===================================================================
--- branches/transforms/src/_backend_agg.cpp	2007年09月19日 19:46:34 UTC (rev 3859)
+++ branches/transforms/src/_backend_agg.cpp	2007年09月19日 19:48:17 UTC (rev 3860)
@@ -87,15 +87,17 @@
 inline void get_next_vertex(const char* & vertex_i, const char* vertex_end, 
 			 double& x, double& y,
 			 size_t next_vertex_stride, 
-			 size_t next_axis_stride) {
+			 size_t next_axis_stride,
+			 const char* & code_i, size_t code_stride) {
 if (vertex_i + next_axis_stride >= vertex_end)
 throw Py::ValueError("Error parsing path. Read past end of vertices");
 x = *(double*)vertex_i;
 y = *(double*)(vertex_i + next_axis_stride);
 vertex_i += next_vertex_stride;
+ code_i += code_stride;
 }
 
-#define GET_NEXT_VERTEX(x, y) get_next_vertex(vertex_i, vertex_end, x, y, next_vertex_stride, next_axis_stride)
+#define GET_NEXT_VERTEX(x, y) get_next_vertex(vertex_i, vertex_end, x, y, next_vertex_stride, next_axis_stride, code_i, code_stride)
 
 Py::Object BufferRegion::to_string(const Py::Tuple &args) {
 
@@ -103,7 +105,71 @@
 return Py::String(PyString_FromStringAndSize((const char*)aggbuf.data,aggbuf.height*aggbuf.stride), true);
 }
 
+class PathIterator {
+ PyArrayObject* vertices;
+ PyArrayObject* codes;
+ size_t m_iterator;
+ size_t m_total_vertices;
 
+public:
+ PathIterator(const Py::Object& path_obj) :
+ vertices(NULL), codes(NULL), m_iterator(0) {
+ Py::Object vertices_obj = path_obj.getAttr("vertices");
+ Py::Object codes_obj = path_obj.getAttr("codes");
+ 
+ vertices = (PyArrayObject*)PyArray_ContiguousFromObject
+ (vertices_obj.ptr(), PyArray_DOUBLE, 2, 2);
+ if (!vertices || vertices->nd != 2 || vertices->dimensions[1] != 2)
+ throw Py::ValueError("Invalid vertices array.");
+ codes = (PyArrayObject*)PyArray_ContiguousFromObject
+ (codes_obj.ptr(), PyArray_UINT8, 1, 1);
+ if (!codes) 
+ throw Py::ValueError("Invalid codes array.");
+ 
+ if (codes->dimensions[0] != vertices->dimensions[0])
+ throw Py::ValueError("Vertices and codes array are not the same length.");
+
+ m_total_vertices = codes->dimensions[0];
+ }
+
+ ~PathIterator() {
+ Py_XDECREF(vertices);
+ Py_XDECREF(codes);
+ }
+
+ static const char code_map[];
+
+ inline unsigned vertex(unsigned idx, double* x, double* y) {
+ if (idx > m_total_vertices)
+ throw Py::RuntimeError("Requested vertex past end");
+ double* pv = (double*)(vertices->data + (idx * vertices->strides[0]));
+ *x = *pv++;
+ *y = *pv;
+ // MGDTODO: Range check
+ return code_map[(unsigned int)*(codes->data + (idx * codes->strides[0]))];
+ }
+
+ inline unsigned vertex(double* x, double* y) {
+ if(m_iterator >= m_total_vertices) return agg::path_cmd_stop;
+ return vertex(m_iterator++, x, y);
+ }
+
+ inline void rewind(unsigned path_id) {
+ m_iterator = path_id;
+ }
+
+ inline unsigned total_vertices() {
+ return m_total_vertices;
+ }
+};
+
+const char PathIterator::code_map[] = {0, 
+				 agg::path_cmd_move_to, 
+				 agg::path_cmd_line_to, 
+				 agg::path_cmd_curve3,
+				 agg::path_cmd_curve4,
+				 agg::path_cmd_end_poly | agg::path_flags_close};
+
 GCAgg::GCAgg(const Py::Object &gc, double dpi, bool snapto) :
 dpi(dpi), snapto(snapto), isaa(true), linewidth(1.0), alpha(1.0),
 cliprect(NULL), clippath(NULL), 
@@ -634,7 +700,7 @@
 if (num_vertices) {
 	for (size_t j=0; j<num_vertices; ++j)
 	 GET_NEXT_VERTEX(x, y);
-	if (code_i == IGNORE)
+	if (*code_i == STOP || *code_i == CLOSEPOLY)
 	 continue;
 
 	trans.transform(&x, &y);
@@ -863,9 +929,10 @@
 
 for (size_t i = 0; i < N; ++i) {
 switch (*(unsigned char*)(code_i)) {
- case IGNORE:
+ case STOP:
 	GET_NEXT_VERTEX(x0, y0);
-	_VERBOSE("IGNORE");
+	_VERBOSE("STOP");
+	// MGDTODO: If this isn't the end, we should raise an error
 	break;
 case MOVETO:
 	GET_NEXT_VERTEX(x0, y0);
@@ -894,10 +961,10 @@
 	break;
 case CLOSEPOLY:
 	close_polygon();
+	GET_NEXT_VERTEX(x0, y0);
 	_VERBOSE("CLOSEPOLY");
 	break;
 }
- code_i += code_stride;
 }
 } catch(...) {
 Py_XDECREF(vertices);
@@ -911,7 +978,7 @@
 
 Py::Object
 RendererAgg::draw_path(const Py::Tuple& args) {
- typedef agg::conv_transform<agg::path_storage> transformed_path_t;
+ typedef agg::conv_transform<PathIterator> transformed_path_t;
 typedef agg::conv_curve<transformed_path_t> curve_t;
 typedef agg::conv_stroke<curve_t> stroke_t;
 typedef agg::conv_dash<curve_t> dash_t;
@@ -928,9 +995,11 @@
 
 GCAgg gc = GCAgg(args[0], dpi);
 Py::Object path_obj = args[1];
- if (!PathAgg::check(path_obj))
- throw Py::TypeError("Native path object is not of correct type");
- PathAgg* path = static_cast<PathAgg*>(path_obj.ptr());
+// if (!PathAgg::check(path_obj))
+// throw Py::TypeError("Native path object is not of correct type");
+ // PathAgg* path = static_cast<PathAgg*>(path_obj.ptr());
+ PathIterator path(path_obj);
+
 agg::trans_affine trans = py_to_agg_transformation_matrix(args[2]);
 facepair_t face = _get_rgba_face(args[3], gc.alpha);
 
@@ -943,34 +1012,34 @@
 bool has_clippath = (gc.clippath != NULL);
 
 if (has_clippath && (gc.clippath != lastclippath || trans != lastclippath_transform)) {
- rendererBaseAlphaMask->clear(agg::gray8(0, 0));
- gc.clippath->rewind(0);
- transformed_path_t transformed_clippath(*(gc.clippath), trans);
- theRasterizer->add_path(transformed_clippath);
- rendererAlphaMask->color(agg::gray8(255, 255));
- agg::render_scanlines(*theRasterizer, *scanlineAlphaMask, *rendererAlphaMask);
- lastclippath = gc.clippath;
- lastclippath_transform = trans;
+// rendererBaseAlphaMask->clear(agg::gray8(0, 0));
+// gc.clippath->rewind(0);
+// transformed_path_t transformed_clippath(*(gc.clippath), trans);
+// theRasterizer->add_path(transformed_clippath);
+// rendererAlphaMask->color(agg::gray8(255, 255));
+// agg::render_scanlines(*theRasterizer, *scanlineAlphaMask, *rendererAlphaMask);
+// lastclippath = gc.clippath;
+// lastclippath_transform = trans;
 }
 
 try {
 // If this is a straight horizontal or vertical line, quantize to nearest 
 // pixels
- if (path->total_vertices() == 2) {
- double x0, y0, x1, y1;
- path->vertex(0, &x0, &y0);
- trans.transform(&x0, &y0);
- path->vertex(1, &x1, &y1);
- trans.transform(&x1, &y1);
- if (((int)x0 == (int)x1) || ((int)y0 == (int)y1)) {
-	new_path.move_to((int)x0 + 0.5, (int)y0 + 0.5);
-	new_path.line_to((int)x1 + 0.5, (int)y1 + 0.5);
-	tpath = new transformed_path_t(new_path, agg::trans_affine());
- }
- }
+// if (path.total_vertices() == 2) {
+// double x0, y0, x1, y1;
+// path.vertex(0, &x0, &y0);
+// trans.transform(&x0, &y0);
+// path.vertex(1, &x1, &y1);
+// trans.transform(&x1, &y1);
+// if (((int)x0 == (int)x1) || ((int)y0 == (int)y1)) {
+// 	new_path.move_to((int)x0 + 0.5, (int)y0 + 0.5);
+// 	new_path.line_to((int)x1 + 0.5, (int)y1 + 0.5);
+// 	tpath = new transformed_path_t(new_path, agg::trans_affine());
+// }
+// }
 
 if (!tpath) {
- tpath = new transformed_path_t(*path, trans);
+ tpath = new transformed_path_t(path, trans);
 }
 
 // Benchmarking shows that there is no noticable slowdown to always
Modified: branches/transforms/src/_backend_agg.h
===================================================================
--- branches/transforms/src/_backend_agg.h	2007年09月19日 19:46:34 UTC (rev 3859)
+++ branches/transforms/src/_backend_agg.h	2007年09月19日 19:48:17 UTC (rev 3860)
@@ -40,14 +40,14 @@
 #include "agg_vcgen_markers_term.h"
 
 // These are copied directly from path.py, and must be kept in sync
-#define IGNORE 0
+#define STOP 0
 #define MOVETO 1
 #define LINETO 2
 #define CURVE3 3
 #define CURVE4 4
 #define CLOSEPOLY 5
 
-const size_t NUM_VERTICES[] = { 1, 1, 1, 2, 3, 0 };
+const size_t NUM_VERTICES[] = { 1, 1, 1, 2, 3, 1 };
 
 typedef agg::pixfmt_rgba32 pixfmt;
 typedef agg::renderer_base<pixfmt> renderer_base;
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
From: <md...@us...> - 2007年09月20日 13:58:01
Revision: 3865
 http://matplotlib.svn.sourceforge.net/matplotlib/?rev=3865&view=rev
Author: mdboom
Date: 2007年09月20日 06:57:59 -0700 (2007年9月20日)
Log Message:
-----------
Go all out with iterator (rather than copy) approach, as it is much faster.
Modified Paths:
--------------
 branches/transforms/lib/matplotlib/backend_bases.py
 branches/transforms/lib/matplotlib/backends/backend_agg.py
 branches/transforms/lib/matplotlib/transforms.py
 branches/transforms/src/_backend_agg.cpp
 branches/transforms/src/_backend_agg.h
Modified: branches/transforms/lib/matplotlib/backend_bases.py
===================================================================
--- branches/transforms/lib/matplotlib/backend_bases.py	2007年09月20日 13:57:32 UTC (rev 3864)
+++ branches/transforms/lib/matplotlib/backend_bases.py	2007年09月20日 13:57:59 UTC (rev 3865)
@@ -17,11 +17,6 @@
 class RendererBase:
 """An abstract base class to handle drawing/rendering operations
 """
- # This will cache paths across rendering instances
- # Each subclass of RenderBase should define this a weak-keyed
- # dictionary to hold native paths
- # _native_paths = weakref.WeakKeyDictionary()
- 
 def __init__(self):
 self._texmanager = None
 
@@ -37,43 +32,16 @@
 """
 pass
 
- def _get_cached_native_path(self, path):
-	native_path = self._native_paths.get(path)
-	if native_path is None:
-	 print "CACHE MISS", path
-	 native_path = self.convert_to_native_path(path)
-	 self._native_paths[path] = native_path
-	return native_path
- 
 def draw_path(self, gc, path, transform, rgbFace=None):
 	"""
 	Handles the caching of the native path associated with the
 	given path and calls the underlying backend's _draw_path to
 	actually do the drawing.
 	"""
-	native_path = self._get_cached_native_path(path)
-	self._draw_native_path(gc, native_path, transform, rgbFace)
+ # MGDTODO: Update docstring
+ raise NotImplementedError
 
- def _draw_native_path(self, gc, native_path, transform, rgbFace):
-	"""
-	Draw the native path object with the given GraphicsContext and
-	transform. The transform passed in will always be affine.
-	"""
-	raise NotImplementedError
-	
- def convert_to_native_path(self, path):
-	"""
-	Backends will normally will override this, but if they don't need any
-	special optimizations, they can just have the generic path data
-	passed to them in draw_path.
-	"""
-	return path
-
 def draw_markers(self, gc, marker_path, marker_trans, path, trans, rgbFace=None):
-	native_marker_path = self._get_cached_native_path(marker_path)
-	self._draw_native_markers(gc, native_marker_path, marker_trans, path, trans, rgbFace)
-	
- def _draw_native_markers(self, gc, native_marker_path, marker_trans, path, trans, rgbFace=None):
 """
 This method is currently underscore hidden because the
 draw_markers method is being used as a sentinel for newstyle
@@ -94,7 +62,11 @@
 vec6 = transform.as_vec6_val()
 ...backend dependent affine...
 """
+ # MGDTODO: Update docstring
 raise NotImplementedError
+	
+ def _draw_native_markers(self, gc, native_marker_path, marker_trans, path, trans, rgbFace=None):
+ raise NotImplementedError
 
 def get_image_magnification(self):
 """
Modified: branches/transforms/lib/matplotlib/backends/backend_agg.py
===================================================================
--- branches/transforms/lib/matplotlib/backends/backend_agg.py	2007年09月20日 13:57:32 UTC (rev 3864)
+++ branches/transforms/lib/matplotlib/backends/backend_agg.py	2007年09月20日 13:57:59 UTC (rev 3865)
@@ -117,8 +117,8 @@
 				 debug=False)
 if __debug__: verbose.report('RendererAgg.__init__ _RendererAgg done',
 'debug-annoying')
-
-	self.convert_to_native_path = self._renderer.convert_to_native_path
+ self.draw_path = self._renderer.draw_path
+ self.draw_markers = self._renderer.draw_markers
 self.draw_image = self._renderer.draw_image
 self.copy_from_bbox = self._renderer.copy_from_bbox
 self.restore_region = self._renderer.restore_region
@@ -129,16 +129,6 @@
 if __debug__: verbose.report('RendererAgg.__init__ done',
 'debug-annoying')
 
- def _draw_native_path(self, gc, path, transform, rgbFace):
-	return self._renderer.draw_path(gc, path, transform.get_matrix(), rgbFace)
- 
- def _draw_native_markers(self, gc, native_marker_path, marker_trans, path, trans, rgbFace=None):
-	return self._renderer.draw_markers(
-	 gc,
-	 native_marker_path, marker_trans.get_matrix(),
-	 path.vertices, path.codes, trans.get_matrix(),
-	 rgbFace)
-
 def draw_mathtext(self, gc, x, y, s, prop, angle):
 """
 Draw the math text using matplotlib.mathtext
Modified: branches/transforms/lib/matplotlib/transforms.py
===================================================================
--- branches/transforms/lib/matplotlib/transforms.py	2007年09月20日 13:57:32 UTC (rev 3864)
+++ branches/transforms/lib/matplotlib/transforms.py	2007年09月20日 13:57:59 UTC (rev 3865)
@@ -365,7 +365,7 @@
 Transform.__init__(self)
 self._inverted = None
 
- def __array__(self):
+ def __array__(self, *args, **kwargs):
 	return self.get_matrix()
 	
 def _do_invalidation(self):
Modified: branches/transforms/src/_backend_agg.cpp
===================================================================
--- branches/transforms/src/_backend_agg.cpp	2007年09月20日 13:57:32 UTC (rev 3864)
+++ branches/transforms/src/_backend_agg.cpp	2007年09月20日 13:57:59 UTC (rev 3865)
@@ -48,59 +48,42 @@
 agg::trans_affine py_to_agg_transformation_matrix(const Py::Object& obj) {
 PyArrayObject* matrix = NULL;
 
- double a = 1.0, b = 0.0, c = 0.0, d = 1.0, e = 0.0, f = 0.0;
-
 try {
- matrix = (PyArrayObject*) PyArray_ContiguousFromObject(obj.ptr(), PyArray_DOUBLE, 2, 2);
- if (!matrix || matrix->nd != 2 || matrix->dimensions[0] != 3 || matrix->dimensions[1] != 3) {
- throw Py::ValueError("Invalid affine transformation matrix.");
+ matrix = (PyArrayObject*) PyArray_FromObject(obj.ptr(), PyArray_DOUBLE, 2, 2);
+ if (!matrix) {
+ throw Py::Exception();
 }
-
- size_t stride0 = matrix->strides[0];
- size_t stride1 = matrix->strides[1];
- char* row0 = matrix->data;
- char* row1 = row0 + stride0;
-
- a = *(double*)(row0);
- row0 += stride1;
- c = *(double*)(row0);
- row0 += stride1;
- e = *(double*)(row0);
- 
- b = *(double*)(row1);
- row1 += stride1;
- d = *(double*)(row1);
- row1 += stride1;
- f = *(double*)(row1);
+ if (matrix->nd == 2 || matrix->dimensions[0] == 3 || matrix->dimensions[1] == 3) {
+ size_t stride0 = matrix->strides[0];
+ size_t stride1 = matrix->strides[1];
+ char* row0 = matrix->data;
+ char* row1 = row0 + stride0;
+ 
+ double a = *(double*)(row0);
+ row0 += stride1;
+ double c = *(double*)(row0);
+ row0 += stride1;
+ double e = *(double*)(row0);
+ 
+ double b = *(double*)(row1);
+ row1 += stride1;
+ double d = *(double*)(row1);
+ row1 += stride1;
+ double f = *(double*)(row1);
+ 
+ Py_XDECREF(matrix);
+ 
+ return agg::trans_affine(a, b, c, d, e, f);
+ }
 } catch (...) {
- Py_XDECREF(matrix);
+ 
 }
 
 Py_XDECREF(matrix);
-
- return agg::trans_affine(a, b, c, d, e, f);
+ throw Py::TypeError("Invalid affine transformation matrix");
 }
 
-/** Helper function to get the next vertex in a Numpy array of vertices.
- * Will generally be used through the GET_NEXT_VERTEX macro.
- */
-inline void get_next_vertex(const char* & vertex_i, const char* vertex_end, 
-			 double& x, double& y,
-			 size_t next_vertex_stride, 
-			 size_t next_axis_stride,
-			 const char* & code_i, size_t code_stride) {
- if (vertex_i + next_axis_stride >= vertex_end)
- throw Py::ValueError("Error parsing path. Read past end of vertices");
- x = *(double*)vertex_i;
- y = *(double*)(vertex_i + next_axis_stride);
- vertex_i += next_vertex_stride;
- code_i += code_stride;
-}
-
-#define GET_NEXT_VERTEX(x, y) get_next_vertex(vertex_i, vertex_end, x, y, next_vertex_stride, next_axis_stride, code_i, code_stride)
-
 Py::Object BufferRegion::to_string(const Py::Tuple &args) {
- 
 // owned=true to prevent memory leak
 return Py::String(PyString_FromStringAndSize((const char*)aggbuf.data,aggbuf.height*aggbuf.stride), true);
 }
@@ -145,7 +128,6 @@
 double* pv = (double*)(vertices->data + (idx * vertices->strides[0]));
 *x = *pv++;
 *y = *pv;
- // MGDTODO: Range check
 return code_map[(unsigned int)*(codes->data + (idx * codes->strides[0]))];
 }
 
@@ -170,9 +152,43 @@
 				 agg::path_cmd_curve4,
 				 agg::path_cmd_end_poly | agg::path_flags_close};
 
+template<class VertexSource> class conv_quantize
+{
+public:
+ conv_quantize(VertexSource& source, bool quantize) :
+ m_source(&source), m_quantize(quantize) {}
+ 
+ void set_source(VertexSource& source) { m_source = &source; }
+
+ void rewind(unsigned path_id) 
+ { 
+ m_source->rewind(path_id); 
+ }
+
+ unsigned vertex(double* x, double* y)
+ {
+ unsigned cmd = m_source->vertex(x, y);
+ if(m_quantize && agg::is_vertex(cmd))
+ {
+	*x = (int)(*x);
+	*y = (int)(*y);
+ }
+ return cmd;
+ }
+
+ void activate(bool quantize) {
+ m_quantize = quantize;
+ }
+
+private:
+ VertexSource* m_source;
+ bool m_quantize;
+};
+
+
 GCAgg::GCAgg(const Py::Object &gc, double dpi, bool snapto) :
 dpi(dpi), snapto(snapto), isaa(true), linewidth(1.0), alpha(1.0),
- cliprect(NULL), clippath(NULL), 
+ cliprect(NULL), 
 Ndash(0), dashOffset(0.0), dasha(NULL)
 {
 _VERBOSE("GCAgg::GCAgg");
@@ -316,15 +332,7 @@
 
 _VERBOSE("GCAgg::_set_clip_path");
 
- Py_XINCREF(clippath);
- clippath = NULL;
- 
- Py::Object o = gc.getAttr("_clippath");
- if (o.ptr()==Py_None) {
- return;
- }
- 
- clippath = new PathAgg(o);
+ clippath = gc.getAttr("_clippath");
 }
 
 
@@ -337,8 +345,7 @@
 height(height),
 dpi(dpi),
 NUMBYTES(width*height*4),
- debug(debug),
- lastclippath(NULL)
+ debug(debug)
 {
 _VERBOSE("RendererAgg::RendererAgg");
 unsigned stride(width*4);
@@ -599,7 +606,7 @@
 
 Py::Object
 RendererAgg::draw_markers(const Py::Tuple& args) {
- typedef agg::conv_transform<agg::path_storage> transformed_path_t;
+ typedef agg::conv_transform<PathIterator> transformed_path_t;
 typedef agg::conv_curve<transformed_path_t> curve_t;
 typedef agg::conv_stroke<curve_t> stroke_t;
 typedef agg::conv_dash<curve_t> dash_t;
@@ -607,27 +614,29 @@
 
 theRasterizer->reset_clipping();
 
- args.verify_length(7);
+ args.verify_length(5, 6);
 
 GCAgg gc = GCAgg(args[0], dpi);
 Py::Object marker_path_obj = args[1];
- if (!PathAgg::check(marker_path_obj))
- throw Py::TypeError("Native path object is not of correct type");
- PathAgg* marker_path = static_cast<PathAgg*>(marker_path_obj.ptr());
 agg::trans_affine marker_trans = py_to_agg_transformation_matrix(args[2]);
- Py::Object vertices_obj = args[3];
- Py::Object codes_obj = args[4];
- agg::trans_affine trans = py_to_agg_transformation_matrix(args[5]);
- facepair_t face = _get_rgba_face(args[6], gc.alpha);
+ Py::Object path_obj = args[3];
+ agg::trans_affine trans = py_to_agg_transformation_matrix(args[4]);
+ Py::Object face_obj;
+ if (args.size() == 6)
+ face_obj = args[5];
+ facepair_t face = _get_rgba_face(face_obj, gc.alpha);
 
 // Deal with the difference in y-axis direction
 marker_trans *= agg::trans_affine_scaling(1.0, -1.0);
 trans *= agg::trans_affine_scaling(1.0, -1.0);
 trans *= agg::trans_affine_translation(0.0, (double)height);
 
- marker_path->rewind(0);
- transformed_path_t marker_path_transformed(*marker_path, marker_trans);
+ PathIterator marker_path(marker_path_obj);
+ transformed_path_t marker_path_transformed(marker_path, marker_trans);
 curve_t marker_path_curve(marker_path_transformed);
+
+ PathIterator path(path_obj);
+ transformed_path_t path_transformed(path, trans);
 
 //maxim's suggestions for cached scanlines
 agg::scanline_storage_aa8 scanlines;
@@ -635,19 +644,8 @@
 
 agg::int8u* fillCache = NULL;
 agg::int8u* strokeCache = NULL;
- PyArrayObject* vertices = NULL;
- PyArrayObject* codes = NULL;
 
 try {
- vertices = (PyArrayObject*)PyArray_ContiguousFromObject
- (vertices_obj.ptr(), PyArray_DOUBLE, 2, 2);
- if (!vertices || vertices->nd != 2 || vertices->dimensions[1] != 2)
- throw Py::ValueError("Invalid vertices array.");
- codes = (PyArrayObject*)PyArray_ContiguousFromObject
- (codes_obj.ptr(), PyArray_UINT8, 1, 1);
- if (!codes) 
- throw Py::ValueError("Invalid codes array.");
-
 unsigned fillSize = 0;
 if (face.first) {
 theRasterizer->add_path(marker_path_curve);
@@ -681,53 +679,29 @@
 rendererBase->clip_box(l, height-(b+h),l+w, height-b);
 }
 
- size_t next_vertex_stride = vertices->strides[0];
- size_t next_axis_stride = vertices->strides[1];
- size_t code_stride = codes->strides[0];
-
- const char* vertex_i = vertices->data;
- const char* code_i = codes->data;
- const char* vertex_end = vertex_i + (vertices->dimensions[0] * vertices->strides[0]);
-
- size_t N = codes->dimensions[0];
 double x, y;
 
 agg::serialized_scanlines_adaptor_aa8 sa;
 agg::serialized_scanlines_adaptor_aa8::embedded_scanline sl;
 
- for (size_t i=0; i < N; i++) {
- size_t num_vertices = NUM_VERTICES[(int)(*code_i)];
- if (num_vertices) {
-	for (size_t j=0; j<num_vertices; ++j)
-	 GET_NEXT_VERTEX(x, y);
-	if (*code_i == STOP || *code_i == CLOSEPOLY)
-	 continue;
-
-	trans.transform(&x, &y);
-	
-	if (face.first) {
-	 //render the fill
-	 sa.init(fillCache, fillSize, x, y);
-	 rendererAA->color(face.second);
-	 agg::render_scanlines(sa, sl, *rendererAA);
-	}
-
-	//render the stroke
-	sa.init(strokeCache, strokeSize, x, y);
-	rendererAA->color(gc.color);
+ while (path_transformed.vertex(&x, &y) != agg::path_cmd_stop) {
+ if (face.first) {
+	//render the fill
+	sa.init(fillCache, fillSize, x, y);
+	rendererAA->color(face.second);
 	agg::render_scanlines(sa, sl, *rendererAA);
 }
- code_i += code_stride;
+ 
+ //render the stroke
+ sa.init(strokeCache, strokeSize, x, y);
+ rendererAA->color(gc.color);
+ agg::render_scanlines(sa, sl, *rendererAA);
 }
 } catch(...) {
- Py_XDECREF(vertices);
- Py_XDECREF(codes);
 delete[] fillCache;
 delete[] strokeCache;
 }
 
- Py_XDECREF(vertices);
- Py_XDECREF(codes);
 delete [] fillCache;
 delete [] strokeCache;
 
@@ -888,98 +862,12 @@
 
 }
 
-Py::Object
-RendererAgg::convert_to_native_path(const Py::Tuple& args) {
- _VERBOSE("RendererAgg::draw_image");
- args.verify_length(1);
- 
- Py::Object path = args[0];
 
- return Py::asObject(new PathAgg(path));
-}
-
- 
-PathAgg::PathAgg(const Py::Object& path_obj) : curvy(false) {
- Py::Object vertices_obj = path_obj.getAttr("vertices");
- Py::Object codes_obj = path_obj.getAttr("codes");
- 
- PyArrayObject* vertices = NULL;
- PyArrayObject* codes = NULL;
-
- try {
- vertices = (PyArrayObject*)PyArray_ContiguousFromObject
- (vertices_obj.ptr(), PyArray_DOUBLE, 2, 2);
- if (!vertices || vertices->nd != 2 || vertices->dimensions[1] != 2)
- throw Py::ValueError("Invalid vertices array.");
- codes = (PyArrayObject*)PyArray_ContiguousFromObject
- (codes_obj.ptr(), PyArray_UINT8, 1, 1);
- if (!codes) 
- throw Py::ValueError("Invalid codes array.");
-
- size_t next_vertex_stride = vertices->strides[0];
- size_t next_axis_stride = vertices->strides[1];
- size_t code_stride = codes->strides[0];
-
- const char* vertex_i = vertices->data;
- const char* code_i = codes->data;
- const char* vertex_end = vertex_i + (vertices->dimensions[0] * vertices->strides[0]);
-
- size_t N = codes->dimensions[0];
- double x0, y0, x1, y1, x2, y2;
-
- for (size_t i = 0; i < N; ++i) {
- switch (*(unsigned char*)(code_i)) {
- case STOP:
-	GET_NEXT_VERTEX(x0, y0);
-	_VERBOSE("STOP");
-	// MGDTODO: If this isn't the end, we should raise an error
-	break;
- case MOVETO:
-	GET_NEXT_VERTEX(x0, y0);
-	move_to(x0, y0);
-	_VERBOSE("MOVETO");
-	break;
- case LINETO:
-	GET_NEXT_VERTEX(x0, y0);
-	line_to(x0, y0);
-	_VERBOSE("LINETO");
-	break;
- case CURVE3:
-	GET_NEXT_VERTEX(x0, y0);
-	GET_NEXT_VERTEX(x1, y1);
-	curve3(x0, y0, x1, y1);
-	curvy = true;
-	_VERBOSE("CURVE3");
-	break;
- case CURVE4:
-	GET_NEXT_VERTEX(x0, y0);
-	GET_NEXT_VERTEX(x1, y1);
-	GET_NEXT_VERTEX(x2, y2);
-	curve4(x0, y0, x1, y1, x2, y2);
-	curvy = true;
-	_VERBOSE("CURVE4");
-	break;
- case CLOSEPOLY:
-	close_polygon();
-	GET_NEXT_VERTEX(x0, y0);
-	_VERBOSE("CLOSEPOLY");
-	break;
- }
- }
- } catch(...) {
- Py_XDECREF(vertices);
- Py_XDECREF(codes);
- throw;
- }
-
- Py_XDECREF(vertices);
- Py_XDECREF(codes);
-}
-
 Py::Object
 RendererAgg::draw_path(const Py::Tuple& args) {
 typedef agg::conv_transform<PathIterator> transformed_path_t;
- typedef agg::conv_curve<transformed_path_t> curve_t;
+ typedef conv_quantize<transformed_path_t> quantize_t;
+ typedef agg::conv_curve<quantize_t> curve_t;
 typedef agg::conv_stroke<curve_t> stroke_t;
 typedef agg::conv_dash<curve_t> dash_t;
 typedef agg::conv_stroke<dash_t> stroke_dash_t;
@@ -991,61 +879,59 @@
 theRasterizer->reset_clipping();
 
 _VERBOSE("RendererAgg::draw_path");
- args.verify_length(4);
+ args.verify_length(3, 4);
 
- GCAgg gc = GCAgg(args[0], dpi);
+ Py::Object gc_obj = args[0];
 Py::Object path_obj = args[1];
-// if (!PathAgg::check(path_obj))
-// throw Py::TypeError("Native path object is not of correct type");
- // PathAgg* path = static_cast<PathAgg*>(path_obj.ptr());
 PathIterator path(path_obj);
 
 agg::trans_affine trans = py_to_agg_transformation_matrix(args[2]);
- facepair_t face = _get_rgba_face(args[3], gc.alpha);
 
 trans *= agg::trans_affine_scaling(1.0, -1.0);
 trans *= agg::trans_affine_translation(0.0, (double)height);
 
- transformed_path_t* tpath = NULL;
- agg::path_storage new_path;
+ bool snap = false;
+ if (path.total_vertices() == 2) {
+ double x0, y0, x1, y1;
+ path.vertex(0, &x0, &y0);
+ trans.transform(&x0, &y0);
+ path.vertex(1, &x1, &y1);
+ trans.transform(&x1, &y1);
+ snap = ((int)x0 == (int)x1) || ((int)y0 == (int)y1);
+ }
 
- bool has_clippath = (gc.clippath != NULL);
+ GCAgg gc = GCAgg(gc_obj, dpi, snap);
+ Py::Object face_obj;
+ if (args.size() == 4)
+ face_obj = args[3];
+ facepair_t face = _get_rgba_face(face_obj, gc.alpha);
 
- if (has_clippath && (gc.clippath != lastclippath || trans != lastclippath_transform)) {
-// rendererBaseAlphaMask->clear(agg::gray8(0, 0));
-// gc.clippath->rewind(0);
-// transformed_path_t transformed_clippath(*(gc.clippath), trans);
-// theRasterizer->add_path(transformed_clippath);
-// rendererAlphaMask->color(agg::gray8(255, 255));
-// agg::render_scanlines(*theRasterizer, *scanlineAlphaMask, *rendererAlphaMask);
-// lastclippath = gc.clippath;
-// lastclippath_transform = trans;
+ bool has_clippath = (gc.clippath.ptr() != Py_None);
+
+ if (has_clippath && 
+ (gc.clippath.ptr() != lastclippath.ptr() || trans != lastclippath_transform)) {
+ PathIterator clippath(gc.clippath);
+ rendererBaseAlphaMask->clear(agg::gray8(0, 0));
+ transformed_path_t transformed_clippath(clippath, trans);
+ agg::conv_curve<transformed_path_t> curved_clippath(transformed_clippath);
+ theRasterizer->add_path(curved_clippath);
+ rendererAlphaMask->color(agg::gray8(255, 255));
+ agg::render_scanlines(*theRasterizer, *scanlineAlphaMask, *rendererAlphaMask);
+ lastclippath = gc.clippath;
+ lastclippath_transform = trans;
 }
 
 try {
 // If this is a straight horizontal or vertical line, quantize to nearest 
 // pixels
-// if (path.total_vertices() == 2) {
-// double x0, y0, x1, y1;
-// path.vertex(0, &x0, &y0);
-// trans.transform(&x0, &y0);
-// path.vertex(1, &x1, &y1);
-// trans.transform(&x1, &y1);
-// if (((int)x0 == (int)x1) || ((int)y0 == (int)y1)) {
-// 	new_path.move_to((int)x0 + 0.5, (int)y0 + 0.5);
-// 	new_path.line_to((int)x1 + 0.5, (int)y1 + 0.5);
-// 	tpath = new transformed_path_t(new_path, agg::trans_affine());
-// }
-// }
 
- if (!tpath) {
- tpath = new transformed_path_t(path, trans);
- }
+ transformed_path_t tpath(path, trans);
+ quantize_t quantized(tpath, snap);
 
 // Benchmarking shows that there is no noticable slowdown to always
 // treating paths as having curved segments. Doing so greatly 
 // simplifies the code
- curve_t curve(*tpath);
+ curve_t curve(quantized);
 
 set_clipbox_rasterizer(gc.cliprect);
 
@@ -1106,12 +992,11 @@
 }
 }
 } catch (...) {
- delete tpath;
+ // MGDTODO: We don't have anything on the heap, so this catch
+ // clause isn't really necessary, but we might again soon...
 throw;
 }
 
- delete tpath;
-
 return Py::Object();
 }
 
@@ -1446,11 +1331,9 @@
 behaviors().doc("The agg backend extension module");
 
 add_varargs_method("draw_path", &RendererAgg::draw_path,
-		 "draw_path(gc, rgbFace, native_path, transform)\n");
- add_varargs_method("convert_to_native_path", &RendererAgg::convert_to_native_path,
-		 "convert_to_native_path(vertices, codes)\n");
+		 "draw_path(gc, path, transform, rgbFace)\n");
 add_varargs_method("draw_markers", &RendererAgg::draw_markers,
-		 "draw_markers(gc, marker_path, marker_trans, vertices, codes, rgbFace)\n");
+		 "draw_markers(gc, marker_path, marker_trans, path, rgbFace)\n");
 add_varargs_method("draw_text_image", &RendererAgg::draw_text_image,
 		 "draw_text_image(font_image, x, y, r, g, b, a)\n");
 add_varargs_method("draw_image", &RendererAgg::draw_image,
@@ -1476,12 +1359,6 @@
 		 "restore_region(region)");
 }
 
-void PathAgg::init_type()
-{
- behaviors().name("PathAgg");
- behaviors().doc("A native Agg path object");
-}
-
 extern "C"
 DL_EXPORT(void)
 init_backend_agg(void)
Modified: branches/transforms/src/_backend_agg.h
===================================================================
--- branches/transforms/src/_backend_agg.h	2007年09月20日 13:57:32 UTC (rev 3864)
+++ branches/transforms/src/_backend_agg.h	2007年09月20日 13:57:59 UTC (rev 3865)
@@ -105,20 +105,6 @@
 };
 };
 
-// A completely opaque data type used only to pass native path
-// data to/from Python. Python can't do anything with the data
-// other than create and then use it.
-class PathAgg : 
- public agg::path_storage, 
- public Py::PythonExtension<PathAgg> {
-public:
- static void init_type(void);
-
- PathAgg(const Py::Object& path_obj);
-
- bool curvy;
-};
-
 class GCAgg {
 public:
 GCAgg(const Py::Object& gc, double dpi, bool snapto=false);
@@ -126,7 +112,6 @@
 ~GCAgg() {
 delete [] dasha;
 delete [] cliprect;
- Py_XINCREF(clippath);
 }
 
 double dpi;
@@ -142,7 +127,7 @@
 agg::rgba color;
 
 double *cliprect;
- PathAgg *clippath;
+ Py::Object clippath;
 //dashes
 size_t Ndash;
 double dashOffset;
@@ -183,7 +168,6 @@
 Py::Object draw_text_image(const Py::Tuple & args);
 Py::Object draw_image(const Py::Tuple & args);
 Py::Object draw_path(const Py::Tuple & args);
- Py::Object convert_to_native_path(const Py::Tuple & args);
 
 Py::Object write_rgba(const Py::Tuple & args);
 Py::Object write_png(const Py::Tuple & args);
@@ -240,7 +224,7 @@
 void set_clipbox_rasterizer( double *cliprect);
 
 private:
- PathAgg *lastclippath;
+ Py::Object lastclippath;
 agg::trans_affine lastclippath_transform;
 };
 
@@ -253,7 +237,6 @@
 : Py::ExtensionModule<_backend_agg_module>( "_backend_agg" )
 {
 RendererAgg::init_type();
- PathAgg::init_type();
 
 add_keyword_method("RendererAgg", &_backend_agg_module::new_renderer,
 		 "RendererAgg(width, height, dpi)");
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
From: <md...@us...> - 2007年09月20日 13:59:16
Revision: 3866
 http://matplotlib.svn.sourceforge.net/matplotlib/?rev=3866&view=rev
Author: mdboom
Date: 2007年09月20日 06:59:15 -0700 (2007年9月20日)
Log Message:
-----------
Merged revisions 3847-3865 via svnmerge from 
http://matplotlib.svn.sf.net/svnroot/matplotlib/trunk/matplotlib
........
 r3853 | jouni | 2007年09月15日 00:01:56 -0400 (2007年9月15日) | 2 lines
 
 Bugfix and doc fixes in type1font.py
........
 r3861 | mdboom | 2007年09月20日 08:31:26 -0400 (2007年9月20日) | 2 lines
 
 Fix font.size from being saved in the fontManager.cache
........
 r3862 | mdboom | 2007年09月20日 08:40:41 -0400 (2007年9月20日) | 2 lines
 
 Removing debugging output in last commit.
........
 r3863 | jdh2358 | 2007年09月20日 09:50:27 -0400 (2007年9月20日) | 1 line
 
 added gradient bar example
........
Modified Paths:
--------------
 branches/transforms/lib/matplotlib/font_manager.py
Added Paths:
-----------
 branches/transforms/examples/gradient_bar.py
Property Changed:
----------------
 branches/transforms/
Property changes on: branches/transforms
___________________________________________________________________
Name: svnmerge-integrated
 - /trunk/matplotlib:1-3846
 + /trunk/matplotlib:1-3865
Copied: branches/transforms/examples/gradient_bar.py (from rev 3863, trunk/matplotlib/examples/gradient_bar.py)
===================================================================
--- branches/transforms/examples/gradient_bar.py	 (rev 0)
+++ branches/transforms/examples/gradient_bar.py	2007年09月20日 13:59:15 UTC (rev 3866)
@@ -0,0 +1,26 @@
+from pylab import figure, show, nx, cm
+
+def gbar(ax, x, y, width=0.5, bottom=0):
+ X = [[.6, .6],[.7,.7]]
+ for left,top in zip(x, y):
+ right = left+width
+ ax.imshow(X, interpolation='bicubic', cmap=cm.Blues,
+ extent=(left, right, bottom, top), alpha=1)
+
+fig = figure()
+
+xmin, xmax = xlim = 0,10
+ymin, ymax = ylim = 0,1
+ax = fig.add_subplot(111, xlim=xlim, ylim=ylim,
+ autoscale_on=False)
+X = [[.6, .6],[.7,.7]]
+
+ax.imshow(X, interpolation='bicubic', cmap=cm.copper,
+ extent=(xmin, xmax, ymin, ymax), alpha=1)
+
+N = 10
+x = nx.arange(N)+0.25
+y = nx.mlab.rand(N)
+gbar(ax, x, y, width=0.7)
+ax.set_aspect('normal')
+show()
Modified: branches/transforms/lib/matplotlib/font_manager.py
===================================================================
--- branches/transforms/lib/matplotlib/font_manager.py	2007年09月20日 13:57:59 UTC (rev 3865)
+++ branches/transforms/lib/matplotlib/font_manager.py	2007年09月20日 13:59:15 UTC (rev 3866)
@@ -843,10 +843,9 @@
 """
 
 def __init__(self, size=None, weight='normal'):
- if not size : size = rcParams['font.size']
- self.__default_size = size
 self.__default_weight = weight
-
+ self.default_size = size
+ 
 paths = [os.path.join(rcParams['datapath'],'fonts','ttf'),
 os.path.join(rcParams['datapath'],'fonts','afm')]
 
@@ -899,7 +898,9 @@
 
 def get_default_size(self):
 "Return the default font size."
- return self.__default_size
+ if self.default_size is None:
+ return rcParams['font.size']
+ return self.default_size
 
 def set_default_weight(self, weight):
 "Set the default font weight. The initial value is 'normal'."
@@ -1085,6 +1086,7 @@
 
 try:
 fontManager = pickle_load(_fmcache)
+ fontManager.default_size = None
 verbose.report("Using fontManager instance from %s" % _fmcache)
 except:
 _rebuild()
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
From: <md...@us...> - 2007年09月20日 18:03:02
Revision: 3870
 http://matplotlib.svn.sourceforge.net/matplotlib/?rev=3870&view=rev
Author: mdboom
Date: 2007年09月20日 11:02:51 -0700 (2007年9月20日)
Log Message:
-----------
Merged revisions 3866-3869 via svnmerge from 
http://matplotlib.svn.sf.net/svnroot/matplotlib/trunk/matplotlib
........
 r3867 | jdh2358 | 2007年09月20日 10:13:51 -0400 (2007年9月20日) | 1 line
 
 committed rectangle selector lock patch
........
Modified Paths:
--------------
 branches/transforms/lib/matplotlib/mlab.py
 branches/transforms/lib/matplotlib/widgets.py
Property Changed:
----------------
 branches/transforms/
Property changes on: branches/transforms
___________________________________________________________________
Name: svnmerge-integrated
 - /trunk/matplotlib:1-3865
 + /trunk/matplotlib:1-3869
Modified: branches/transforms/lib/matplotlib/mlab.py
===================================================================
--- branches/transforms/lib/matplotlib/mlab.py	2007年09月20日 18:00:32 UTC (rev 3869)
+++ branches/transforms/lib/matplotlib/mlab.py	2007年09月20日 18:02:51 UTC (rev 3870)
@@ -1255,7 +1255,7 @@
 if unpack: return X.transpose()
 else: return X
 
-def csv2rec(fname, comments='#', skiprows=1, checkrows=5, delimiter=',',
+def csv2rec(fname, comments='#', skiprows=0, checkrows=5, delimiter=',',
 converterd=None, names=None, missing=None):
 """
 Load data from comma/space/tab delimited file in fname into a
@@ -1314,6 +1314,14 @@
 else: return get_func(item, funcmap[func]) # recurse
 else: return func
 
+
+ # map column names that clash with builtins -- TODO - extend this list
+ itemd = {
+ 'return' : 'return_',
+ 'file' : 'file_',
+ 'print' : 'print_',
+ }
+ 
 def get_converters(reader):
 
 converters = None
@@ -1352,6 +1360,7 @@
 if not len(item):
 item = 'column%d'%i
 
+ item = itemd.get(item, item)
 cnt = seen.get(item, 0)
 if cnt>0:
 names.append(item + '%d'%cnt)
Modified: branches/transforms/lib/matplotlib/widgets.py
===================================================================
--- branches/transforms/lib/matplotlib/widgets.py	2007年09月20日 18:00:32 UTC (rev 3869)
+++ branches/transforms/lib/matplotlib/widgets.py	2007年09月20日 18:02:51 UTC (rev 3870)
@@ -955,24 +955,40 @@
 warnings.warn('Use SpanSelector instead!', DeprecationWarning)
 SpanSelector.__init__(self, ax, onselect, 'horizontal', **kwargs)
 
+
 class RectangleSelector:
 """
 Select a min/max range of the x axes for a matplotlib Axes
 
 Example usage:
 
- ax = subplot(111)
- ax.plot(x,y)
+ from matplotlib.widgets import RectangleSelector
+ from pylab import *
 
- def onselect(eclick, erelease):
+ def onselect(eclick, erelease):
 'eclick and erelease are matplotlib events at press and release'
- print 'startposition : (%f,%f)'%(eclick.xdata, eclick.ydata)
- print 'endposition : (%f,%f)'%(erelease.xdata, erelease.ydata)
- print 'used button : ', eclick.button
+ print ' startposition : (%f, %f)' % (eclick.xdata, eclick.ydata)
+ print ' endposition : (%f, %f)' % (erelease.xdata, erelease.ydata)
+ print ' used button : ', eclick.button
 
- span = Selector(ax, onselect,drawtype='box')
- show()
+ def toggle_Selector(event):
+ print ' Key pressed.'
+ if event.key in ['Q', 'q'] and toggle_Selector.RS.active:
+ print ' RectangleSelector deactivated.'
+ toggle_Selector.RS.set_active(False)
+ if event.key in ['A', 'a'] and not toggle_Selector.RS.active:
+ print ' RectangleSelector activated.'
+ toggle_Selector.RS.set_active(True)
 
+ x = arange(100)/(99.0)
+ y = sin(x)
+ fig = figure
+ ax = subplot(111)
+ ax.plot(x,y)
+
+ toggle_Selector.RS = RectangleSelector(ax, onselect, drawtype='line')
+ connect('key_press_event', toggle_Selector)
+ show()
 """
 def __init__(self, ax, onselect, drawtype='box',
 minspanx=None, minspany=None, useblit=False,
@@ -1001,8 +1017,6 @@
 Use type if you want the mouse to draw a line, a box or nothing
 between click and actual position ny setting
 drawtype = 'line', drawtype='box' or drawtype = 'none'.
-
-
 """
 self.ax = ax
 self.visible = True
@@ -1012,6 +1026,7 @@
 self.canvas.mpl_connect('button_release_event', self.release)
 self.canvas.mpl_connect('draw_event', self.update_background)
 
+ self.active = True # for activation / deactivation
 self.to_draw = None
 self.background = None
 
@@ -1052,6 +1067,14 @@
 
 def ignore(self, event):
 'return True if event should be ignored'
+ # If RectangleSelector is not active :
+ if not self.active:
+ return True
+ 
+ # If canvas was locked
+ if not self.canvas.widgetlock.available(self):
+ return True
+ 
 # If no button was pressed yet ignore the event if it was out
 # of the axes
 if self.eventpress == None:
@@ -1142,6 +1165,17 @@
 self.update()
 return False
 
+ def set_active(self, active):
+ """ Use this to activate / deactivate the RectangleSelector
+
+ from your program with an boolean variable 'active'.
+ """
+ self.active = active
+
+ def get_active(self):
+ """ to get status of active mode (boolean variable)"""
+ return self.active 
+
 class Lasso(Widget):
 def __init__(self, ax, xy, callback=None, useblit=True):
 self.axes = ax
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
From: <md...@us...> - 2007年09月21日 16:54:35
Revision: 3873
 http://matplotlib.svn.sourceforge.net/matplotlib/?rev=3873&view=rev
Author: mdboom
Date: 2007年09月21日 09:54:32 -0700 (2007年9月21日)
Log Message:
-----------
Merged revisions 3870-3872 via svnmerge from 
http://matplotlib.svn.sf.net/svnroot/matplotlib/trunk/matplotlib
........
 r3871 | dsdale | 2007年09月21日 11:33:18 -0400 (2007年9月21日) | 2 lines
 
 changed cbooks reversed to agree with the python builtin
........
Modified Paths:
--------------
 branches/transforms/API_CHANGES
 branches/transforms/CHANGELOG
 branches/transforms/lib/matplotlib/cbook.py
Property Changed:
----------------
 branches/transforms/
Property changes on: branches/transforms
___________________________________________________________________
Name: svnmerge-integrated
 - /trunk/matplotlib:1-3869
 + /trunk/matplotlib:1-3872
Modified: branches/transforms/API_CHANGES
===================================================================
--- branches/transforms/API_CHANGES	2007年09月21日 16:52:50 UTC (rev 3872)
+++ branches/transforms/API_CHANGES	2007年09月21日 16:54:32 UTC (rev 3873)
@@ -1,3 +1,8 @@
+ Changed cbook.reversed so it yields a tuple rather than a 
+ (index, tuple). This agrees with the python reversed builtin,
+ and cbook only defines reversed if python doesnt provide the 
+ builtin.
+
 Made skiprows=1 the default on csv2rec
 
 The gd and paint backends have been deleted.
Modified: branches/transforms/CHANGELOG
===================================================================
--- branches/transforms/CHANGELOG	2007年09月21日 16:52:50 UTC (rev 3872)
+++ branches/transforms/CHANGELOG	2007年09月21日 16:54:32 UTC (rev 3873)
@@ -1,3 +1,6 @@
+2007年09月21日 Changed cbook.reversed to yield the same result as the 
+ python reversed builtin - DSD
+
 2007年09月13日 The usetex support in the pdf backend is more usable now,
 so I am enabling it. - JKS
 
Modified: branches/transforms/lib/matplotlib/cbook.py
===================================================================
--- branches/transforms/lib/matplotlib/cbook.py	2007年09月21日 16:52:50 UTC (rev 3872)
+++ branches/transforms/lib/matplotlib/cbook.py	2007年09月21日 16:54:32 UTC (rev 3873)
@@ -482,7 +482,7 @@
 enumerate() is new in Python 2.3
 """
 for i in range(len(seq)-1,-1,-1):
- yield i, seq[i]
+ yield seq[i]
 
 
 # use itertools.izip if available, else use python version
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
From: <md...@us...> - 2007年09月24日 16:54:40
Revision: 3885
 http://matplotlib.svn.sourceforge.net/matplotlib/?rev=3885&view=rev
Author: mdboom
Date: 2007年09月24日 09:54:37 -0700 (2007年9月24日)
Log Message:
-----------
Merged revisions 3873-3884 via svnmerge from 
http://matplotlib.svn.sf.net/svnroot/matplotlib/trunk/matplotlib
........
 r3874 | jouni | 2007年09月22日 02:48:49 -0400 (2007年9月22日) | 3 lines
 
 Replace some generator expressions by list comprehensions for
 Python 2.3 compatibility
........
 r3879 | dsdale | 2007年09月24日 08:56:38 -0400 (2007年9月24日) | 2 lines
 
 fix backend_qt* bug with multiple plot windows and show()
........
 r3880 | dsdale | 2007年09月24日 09:00:12 -0400 (2007年9月24日) | 2 lines
 
 backend_qt* bugfix for multiple plot windows and show()
........
 r3881 | dsdale | 2007年09月24日 09:01:17 -0400 (2007年9月24日) | 2 lines
 
 fix backend_wxagg reference in new config module
........
 r3882 | dsdale | 2007年09月24日 09:03:01 -0400 (2007年9月24日) | 3 lines
 
 modifed embedding_in_qt* examples so they can be run from ipython with 
 -q*thread
........
 r3883 | dsdale | 2007年09月24日 11:11:58 -0400 (2007年9月24日) | 2 lines
 
 fix bug in improved support for multiple windows in backend_qt4
........
Modified Paths:
--------------
 branches/transforms/CHANGELOG
 branches/transforms/examples/embedding_in_qt.py
 branches/transforms/examples/embedding_in_qt4.py
 branches/transforms/lib/matplotlib/backends/backend_pdf.py
 branches/transforms/lib/matplotlib/backends/backend_qt.py
 branches/transforms/lib/matplotlib/backends/backend_qt4.py
 branches/transforms/lib/matplotlib/config/mpltraits.py
 branches/transforms/lib/matplotlib/dviread.py
Property Changed:
----------------
 branches/transforms/
Property changes on: branches/transforms
___________________________________________________________________
Name: svnmerge-integrated
 - /trunk/matplotlib:1-3872
 + /trunk/matplotlib:1-3884
Modified: branches/transforms/CHANGELOG
===================================================================
--- branches/transforms/CHANGELOG	2007年09月24日 16:53:38 UTC (rev 3884)
+++ branches/transforms/CHANGELOG	2007年09月24日 16:54:37 UTC (rev 3885)
@@ -1,3 +1,7 @@
+2007年09月24日 Applied Eike Welk's patch reported on mpl-dev on 2007年09月22日
+ Fixes a bug with multiple plot windows in the qt backend,
+ ported the changes to backend_qt4 as well - DSD
+
 2007年09月21日 Changed cbook.reversed to yield the same result as the 
 python reversed builtin - DSD
 
Modified: branches/transforms/examples/embedding_in_qt.py
===================================================================
--- branches/transforms/examples/embedding_in_qt.py	2007年09月24日 16:53:38 UTC (rev 3884)
+++ branches/transforms/examples/embedding_in_qt.py	2007年09月24日 16:54:37 UTC (rev 3885)
@@ -25,7 +25,7 @@
 
 # Note: color-intensive applications may require a different color allocation
 # strategy.
-QApplication.setColorSpec(QApplication.NormalColor)
+#QApplication.setColorSpec(QApplication.NormalColor)
 app = QApplication(sys.argv)
 
 class MyMplCanvas(FigureCanvas):
@@ -129,12 +129,8 @@
 % {"prog": progname, "version": progversion})
 
 
-def main():
- aw = ApplicationWindow()
- aw.setCaption("%s" % progname)
- qApp.setMainWidget(aw)
- aw.show()
- sys.exit(qApp.exec_loop())
-
-
-if __name__ == "__main__": main()
+aw = ApplicationWindow()
+aw.setCaption("%s" % progname)
+qApp.setMainWidget(aw)
+aw.show()
+sys.exit(qApp.exec_loop())
Modified: branches/transforms/examples/embedding_in_qt4.py
===================================================================
--- branches/transforms/examples/embedding_in_qt4.py	2007年09月24日 16:53:38 UTC (rev 3884)
+++ branches/transforms/examples/embedding_in_qt4.py	2007年09月24日 16:54:37 UTC (rev 3885)
@@ -122,17 +122,10 @@
 % {"prog": progname, "version": progversion})
 
 
-def main():
- # Note: color-intensive applications may require a different color
- # allocation strategy.
- QtGui.QApplication.setColorSpec(QtGui.QApplication.NormalColor)
- qApp = QtGui.QApplication(sys.argv)
+qApp = QtGui.QApplication(sys.argv)
 
- aw = ApplicationWindow()
- aw.setWindowTitle("%s" % progname)
- aw.show()
-# sys.exit(qApp.exec_())
- qApp.exec_()
-
-
-if __name__ == "__main__": main()
+aw = ApplicationWindow()
+aw.setWindowTitle("%s" % progname)
+aw.show()
+sys.exit(qApp.exec_())
+#qApp.exec_()
Modified: branches/transforms/lib/matplotlib/backends/backend_pdf.py
===================================================================
--- branches/transforms/lib/matplotlib/backends/backend_pdf.py	2007年09月24日 16:53:38 UTC (rev 3884)
+++ branches/transforms/lib/matplotlib/backends/backend_pdf.py	2007年09月24日 16:54:37 UTC (rev 3885)
@@ -541,10 +541,10 @@
 widths[ch] = afmdata.get_width_char(ch, isord=True)
 except KeyError:
 pass
- not_None = (ch for ch in range(256) 
- if widths[ch] is not None)
- firstchar = not_None.next()
- lastchar = max(not_None)
+ not_None = [ch for ch in range(256) 
+ if widths[ch] is not None]
+ firstchar = not_None[0]
+ lastchar = not_None[-1]
 widths = widths[firstchar:lastchar+1]
 for i,w in enumerate(widths):
 if w is None: widths[i] = 0
Modified: branches/transforms/lib/matplotlib/backends/backend_qt.py
===================================================================
--- branches/transforms/lib/matplotlib/backends/backend_qt.py	2007年09月24日 16:53:38 UTC (rev 3884)
+++ branches/transforms/lib/matplotlib/backends/backend_qt.py	2007年09月24日 16:54:37 UTC (rev 3885)
@@ -46,11 +46,11 @@
 qApp = qt.QApplication( [" "] )
 qt.QObject.connect( qApp, qt.SIGNAL( "lastWindowClosed()" ),
 qApp, qt.SLOT( "quit()" ) )
- else:
- # someone else aready created the qApp and
- # we let them handle the event-loop control.
- show._needmain = False
+ #remember that matplotlib created the qApp - will be used by show()
+ _create_qApp.qAppCreatedHere = True
 
+_create_qApp.qAppCreatedHere = False
+
 def show():
 """
 Show all the figures and enter the qt main loop
@@ -65,13 +65,10 @@
 if figManager != None:
 figManager.canvas.draw()
 
- if ( show._needmain ):
- qt.qApp.exec_loop()
- show._needmain = False
+ if _create_qApp.qAppCreatedHere:
+ qt.qApp.exec_loop()
 
-show._needmain = True
 
-
 def new_figure_manager( num, *args, **kwargs ):
 """
 Create a new figure manager instance
Modified: branches/transforms/lib/matplotlib/backends/backend_qt4.py
===================================================================
--- branches/transforms/lib/matplotlib/backends/backend_qt4.py	2007年09月24日 16:53:38 UTC (rev 3884)
+++ branches/transforms/lib/matplotlib/backends/backend_qt4.py	2007年09月24日 16:54:37 UTC (rev 3885)
@@ -46,11 +46,11 @@
 qApp = QtGui.QApplication( [" "] )
 QtCore.QObject.connect( qApp, QtCore.SIGNAL( "lastWindowClosed()" ),
 qApp, QtCore.SLOT( "quit()" ) )
- else:
- # someone else aready created the qApp and
- # we let them handle the event-loop control.
- show._needmain = False
+ #remember that matplotlib created the qApp - will be used by show()
+ _create_qApp.qAppCreatedHere = True
 
+_create_qApp.qAppCreatedHere = False
+
 def show():
 """
 Show all the figures and enter the qt main loop
@@ -65,13 +65,10 @@
 if figManager != None:
 figManager.canvas.draw()
 
- if ( show._needmain ):
- qApp.exec_()
- show._needmain = False
+ if _create_qApp.qAppCreatedHere:
+ QtGui.qApp.exec_()
 
-show._needmain = True
 
-
 def new_figure_manager( num, *args, **kwargs ):
 """
 Create a new figure manager instance
Modified: branches/transforms/lib/matplotlib/config/mpltraits.py
===================================================================
--- branches/transforms/lib/matplotlib/config/mpltraits.py	2007年09月24日 16:53:38 UTC (rev 3884)
+++ branches/transforms/lib/matplotlib/config/mpltraits.py	2007年09月24日 16:54:37 UTC (rev 3885)
@@ -29,7 +29,7 @@
 'gtkcairo': 'GTKCairo',
 'qt4agg': 'Qt4Agg',
 'qtagg': 'QtAgg',
- 'wxagg': 'WxAgg',
+ 'wxagg': 'WXAgg',
 'agg': 'Agg',
 'cairo': 'Cairo',
 'ps': 'PS',
Modified: branches/transforms/lib/matplotlib/dviread.py
===================================================================
--- branches/transforms/lib/matplotlib/dviread.py	2007年09月24日 16:53:38 UTC (rev 3884)
+++ branches/transforms/lib/matplotlib/dviread.py	2007年09月24日 16:54:37 UTC (rev 3885)
@@ -350,9 +350,9 @@
 def _xxx(self, special):
 matplotlib.verbose.report(
 'Dvi._xxx: encountered special: %s'
- % ''.join((32 <= ord(ch) < 127) and ch 
- or '<%02x>' % ord(ch)
- for ch in special),
+ % ''.join([(32 <= ord(ch) < 127) and ch 
+ or '<%02x>' % ord(ch)
+ for ch in special]),
 'debug')
 
 def _fnt_def(self, k, c, s, d, a, l, n):
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
From: <md...@us...> - 2007年09月26日 13:55:53
Revision: 3896
 http://matplotlib.svn.sourceforge.net/matplotlib/?rev=3896&view=rev
Author: mdboom
Date: 2007年09月26日 06:55:41 -0700 (2007年9月26日)
Log Message:
-----------
Merged revisions 3885-3895 via svnmerge from 
http://matplotlib.svn.sf.net/svnroot/matplotlib/trunk/matplotlib
........
 r3894 | mdboom | 2007年09月26日 09:41:15 -0400 (2007年9月26日) | 3 lines
 
 Bugfix: Display exponents in tick values in the default font (not the
 default math font)
........
Modified Paths:
--------------
 branches/transforms/lib/matplotlib/mathtext.py
 branches/transforms/lib/matplotlib/ticker.py
Property Changed:
----------------
 branches/transforms/
Property changes on: branches/transforms
___________________________________________________________________
Name: svnmerge-integrated
 - /trunk/matplotlib:1-3884
 + /trunk/matplotlib:1-3895
Modified: branches/transforms/lib/matplotlib/mathtext.py
===================================================================
--- branches/transforms/lib/matplotlib/mathtext.py	2007年09月26日 13:53:53 UTC (rev 3895)
+++ branches/transforms/lib/matplotlib/mathtext.py	2007年09月26日 13:55:41 UTC (rev 3896)
@@ -1855,7 +1855,7 @@
 "tanh")
 
 fontname = oneOf("rm cal it tt sf bf")
- latex2efont = oneOf("mathrm mathcal mathit mathtt mathsf mathbf")
+ latex2efont = oneOf("mathrm mathcal mathit mathtt mathsf mathbf mathdefault")
 
 space =(FollowedBy(bslash)
 + (Literal(r'\ ')
Modified: branches/transforms/lib/matplotlib/ticker.py
===================================================================
--- branches/transforms/lib/matplotlib/ticker.py	2007年09月26日 13:53:53 UTC (rev 3895)
+++ branches/transforms/lib/matplotlib/ticker.py	2007年09月26日 13:55:41 UTC (rev 3896)
@@ -300,9 +300,12 @@
 sciNotStr = r'{\times}'+self.format_data(10**self.orderOfMagnitude)
 else:
 sciNotStr = u'\xd7'+'1e%d'% self.orderOfMagnitude
- if self._useMathText or self._usetex:
+ if self._useMathText:
+ return ''.join(('$\mathdefault{',sciNotStr,offsetStr,'}$'))
+ elif self._usetex:
 return ''.join(('$',sciNotStr,offsetStr,'$'))
- else: return ''.join((sciNotStr,offsetStr))
+ else:
+ return ''.join((sciNotStr,offsetStr))
 else: return ''
 
 def set_locs(self, locs):
@@ -363,8 +366,11 @@
 for loc in locs]
 sigfigs.sort()
 self.format = '%1.' + str(sigfigs[-1]) + 'f'
- if self._usetex or self._useMathText: self.format = '$%s$'%self.format
-
+ if self._usetex:
+ self.format = '$%s$' % self.format
+ elif self._useMathText:
+ self.format = '$\mathdefault{%s}$' % self.format
+ 
 def pprint_val(self, x):
 xp = (x-self.offset)/10**self.orderOfMagnitude
 if npy.absolute(xp) < 1e-8: xp = 0
@@ -511,11 +517,13 @@
 elif not isDecade:
 if usetex:
 s = r'$%d^{%.2f}$'% (b, fx)
- else: s = '$%d^{%.2f}$'% (b, fx)
+ else:
+ s = '$\mathdefault{%d^{%.2f}}$'% (b, fx)
 else:
 if usetex:
 s = r'$%d^{%d}$'% (b, self.nearest_long(fx))
- else: s = r'$%d^{%d}$'% (b, self.nearest_long(fx))
+ else:
+ s = r'$\mathdefault{%d^{%d}}$'% (b, self.nearest_long(fx))
 
 return s
 
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
From: <md...@us...> - 2007年10月01日 11:54:17
Revision: 3906
 http://matplotlib.svn.sourceforge.net/matplotlib/?rev=3906&view=rev
Author: mdboom
Date: 2007年10月01日 04:53:52 -0700 (2007年10月01日)
Log Message:
-----------
Merged revisions 3896-3905 via svnmerge from 
http://matplotlib.svn.sf.net/svnroot/matplotlib/trunk/matplotlib
........
 r3898 | jdh2358 | 2007年09月28日 08:41:08 -0400 (2007年9月28日) | 2 lines
 
 fixed some tick accessor bugs
........
 r3899 | jouni | 2007年09月28日 11:50:01 -0400 (2007年9月28日) | 3 lines
 
 Catch UnboundLocalError in checkdep_pdftops; it is raised if
 no output line of pdftops -v contains the word "version".
........
 r3900 | jouni | 2007年09月28日 11:57:49 -0400 (2007年9月28日) | 2 lines
 
 More debugging output when using TeX with the pdf backend
........
 r3901 | jouni | 2007年09月30日 16:08:50 -0400 (2007年9月30日) | 3 lines
 
 use_tex in pdf backend: don't use AFM files, 
 which are not there in some TeX distros
........
 r3902 | efiring | 2007年09月30日 16:32:31 -0400 (2007年9月30日) | 4 lines
 
 bugfix by Zack, confirmed by Gary Ruben.
 
 http://sourceforge.net/mailarchive/forum.php?thread_name=d8cf9020703071339y43354eaerbfa1a47d272e5d26%40mail.gmail.com&forum_name=matplotlib-users
........
 r3903 | efiring | 2007年09月30日 16:47:55 -0400 (2007年9月30日) | 2 lines
 
 Apply patch by Leon Barrett, tracker #1798196
........
 r3904 | efiring | 2007年10月01日 03:06:43 -0400 (2007年10月01日) | 2 lines
 
 Fixed bug in updating dataLim when an axis is reversed
........
Modified Paths:
--------------
 branches/transforms/CHANGELOG
 branches/transforms/lib/matplotlib/__init__.py
 branches/transforms/lib/matplotlib/axes3d.py
 branches/transforms/lib/matplotlib/axis.py
 branches/transforms/lib/matplotlib/backends/backend_pdf.py
 branches/transforms/lib/matplotlib/dviread.py
 branches/transforms/lib/matplotlib/widgets.py
Property Changed:
----------------
 branches/transforms/
Property changes on: branches/transforms
___________________________________________________________________
Name: svnmerge-integrated
 - /trunk/matplotlib:1-3895
 + /trunk/matplotlib:1-3905
Modified: branches/transforms/CHANGELOG
===================================================================
--- branches/transforms/CHANGELOG	2007年10月01日 11:44:54 UTC (rev 3905)
+++ branches/transforms/CHANGELOG	2007年10月01日 11:53:52 UTC (rev 3906)
@@ -1,3 +1,10 @@
+2007年09月30日 Modified update* methods of Bbox and Interval so they
+ work with reversed axes. Prior to this, trying to
+ set the ticks on a reversed axis failed with an
+ uninformative error message. - EF
+
+2007年09月30日 Applied patches to axes3d to fix index error problem - EF
+
 2007年09月24日 Applied Eike Welk's patch reported on mpl-dev on 2007年09月22日
 Fixes a bug with multiple plot windows in the qt backend,
 ported the changes to backend_qt4 as well - DSD
@@ -2,3 +9,3 @@
 
-2007年09月21日 Changed cbook.reversed to yield the same result as the 
+2007年09月21日 Changed cbook.reversed to yield the same result as the
 python reversed builtin - DSD
Modified: branches/transforms/lib/matplotlib/__init__.py
===================================================================
--- branches/transforms/lib/matplotlib/__init__.py	2007年10月01日 11:44:54 UTC (rev 3905)
+++ branches/transforms/lib/matplotlib/__init__.py	2007年10月01日 11:53:52 UTC (rev 3906)
@@ -270,7 +270,7 @@
 v = line.split()[-1]
 float(v)
 return v
- except (IndexError, ValueError):
+ except (IndexError, ValueError, UnboundLocalError):
 return None
 
 def compare_versions(a, b):
Modified: branches/transforms/lib/matplotlib/axes3d.py
===================================================================
--- branches/transforms/lib/matplotlib/axes3d.py	2007年10月01日 11:44:54 UTC (rev 3905)
+++ branches/transforms/lib/matplotlib/axes3d.py	2007年10月01日 11:53:52 UTC (rev 3906)
@@ -510,16 +510,16 @@
 #
 polys = []
 boxes = []
- for rs in npy.arange(0,rows,rstride):
- for cs in npy.arange(0,cols,cstride):
+ for rs in npy.arange(0,rows-1,rstride):
+ for cs in npy.arange(0,cols-1,cstride):
 ps = []
 corners = []
 for a,ta in [(X,tX),(Y,tY),(Z,tZ)]:
- ztop = a[rs][cs:min(cols-1,cs+cstride)]
+ ztop = a[rs][cs:min(cols,cs+cstride+1)]
 zleft = ta[min(cols-1,cs+cstride)][rs:min(rows,rs+rstride+1)]
 zbase = a[min(rows-1,rs+rstride)][cs:min(cols,cs+cstride+1):]
 zbase = zbase[::-1]
- zright = ta[cs][rs:min(rows-1,rs+rstride):]
+ zright = ta[cs][rs:min(rows,rs+rstride+1):]
 zright = zright[::-1]
 corners.append([ztop[0],ztop[-1],zbase[0],zbase[-1]])
 z = npy.concatenate((ztop,zleft,zbase,zright))
Modified: branches/transforms/lib/matplotlib/axis.py
===================================================================
--- branches/transforms/lib/matplotlib/axis.py	2007年10月01日 11:44:54 UTC (rev 3905)
+++ branches/transforms/lib/matplotlib/axis.py	2007年10月01日 11:53:52 UTC (rev 3906)
@@ -530,8 +530,11 @@
 
 def get_children(self):
 children = [self.label]
- children.extend(self.majorTicks)
- children.extend(self.minorTicks)
+ majorticks = self.get_major_ticks()
+ minorticks = self.get_minor_ticks() 
+ 
+ children.extend(majorticks)
+ children.extend(minorticks)
 return children
 
 def cla(self):
@@ -654,7 +657,8 @@
 
 def get_gridlines(self):
 'Return the grid lines as a list of Line2D instance'
- return silent_list('Line2D gridline', [tick.gridline for tick in self.majorTicks])
+ ticks = self.get_major_ticks()
+ return silent_list('Line2D gridline', [tick.gridline for tick in ticks])
 
 def get_label(self):
 'Return the axis label as a Text instance'
@@ -670,14 +674,16 @@
 
 def get_ticklabels(self):
 'Return a list of Text instances for ticklabels'
- labels1 = [tick.label1 for tick in self.majorTicks if tick.label1On]
- labels2 = [tick.label2 for tick in self.majorTicks if tick.label2On]
+ ticks = self.get_major_ticks()
+ labels1 = [tick.label1 for tick in ticks if tick.label1On]
+ labels2 = [tick.label2 for tick in ticks if tick.label2On]
 return silent_list('Text ticklabel', labels1+labels2)
 
 def get_ticklines(self):
 'Return the ticklines lines as a list of Line2D instance'
 lines = []
- for tick in self.majorTicks:
+ ticks = self.get_major_ticks() 
+ for tick in ticks:
 lines.append(tick.tick1line)
 lines.append(tick.tick2line)
 return silent_list('Line2D ticklines', lines)
@@ -1087,9 +1093,10 @@
 """
 assert position == 'top' or position == 'bottom' or position == 'both' or position == 'default'
 
- ticks = list(self.majorTicks) # a copy
- ticks.extend( self.minorTicks )
 
+ ticks = list( self.get_major_ticks() ) # a copy
+ ticks.extend( self.get_minor_ticks() )
+
 if position == 'top':
 for t in ticks:
 t.tick1On = False
@@ -1287,8 +1294,8 @@
 """
 assert position == 'left' or position == 'right' or position == 'both' or position == 'default'
 
- ticks = list(self.majorTicks) # a copy
- ticks.extend( self.minorTicks )
+ ticks = list( self.get_major_ticks() ) # a copy
+ ticks.extend( self.get_minor_ticks() )
 
 if position == 'right':
 self.set_offset_position('right')
Modified: branches/transforms/lib/matplotlib/backends/backend_pdf.py
===================================================================
--- branches/transforms/lib/matplotlib/backends/backend_pdf.py	2007年10月01日 11:44:54 UTC (rev 3905)
+++ branches/transforms/lib/matplotlib/backends/backend_pdf.py	2007年10月01日 11:53:52 UTC (rev 3906)
@@ -500,70 +500,15 @@
 finally:
 fh.close()
 
- fh = open(fontinfo.afmfile, 'rb')
- matplotlib.verbose.report(
- 'Reading metrics from ' + fontinfo.afmfile, 'debug')
- try:
- afmdata = AFM(fh)
- finally:
- fh.close()
-
 font = FT2Font(filename)
- font.attach_file(fontinfo.afmfile)
 
 widthsObject, fontdescObject, fontdictObject, fontfileObject = \
 [ self.reserveObject(n) for n in
 ('font widths', 'font descriptor',
 'font dictionary', 'font file') ]
 
- _, _, fullname, familyname, weight, italic_angle, fixed_pitch, \
- ul_position, ul_thickness = font.get_ps_font_info()
-
- if fontinfo.encodingfile is not None:
- enc = dviread.Encoding(fontinfo.encodingfile)
- widths = []
- for ch in enc:
- try:
- widths.append(afmdata.get_width_from_char_name(ch))
- except KeyError:
- matplotlib.verbose.report(
- 'No width for %s in %s' % (ch, fullname), 'debug-annoying')
- widths.append(0)
-
- differencesArray = [ Name(ch) for ch in enc ]
- differencesArray = [ 0 ] + differencesArray
- firstchar = 0
- lastchar = len(differencesArray) - 2
- else:
- widths = [ None for i in range(256) ]
- for ch in range(256):
- try:
- widths[ch] = afmdata.get_width_char(ch, isord=True)
- except KeyError:
- pass
- not_None = [ch for ch in range(256) 
- if widths[ch] is not None]
- firstchar = not_None[0]
- lastchar = not_None[-1]
- widths = widths[firstchar:lastchar+1]
- for i,w in enumerate(widths):
- if w is None: widths[i] = 0
-
- differencesArray = [ ]
- need_idx = True
- for ch in range(firstchar, lastchar+1):
- try:
- name = afmdata.get_name_char(ch, isord=True)
- if need_idx:
- differencesArray.append(ch)
- need_idx = False
- differencesArray.append(Name(name))
- except KeyError:
- matplotlib.verbose.report(
- 'No name for glyph %d in %s' % (ch, fullname), 
- 'debug-annoying')
- need_idx = True
-
+ firstchar = 0
+ lastchar = len(fontinfo.widths) - 1
 
 fontdict = {
 'Type': Name('Font'),
@@ -575,15 +520,22 @@
 'FontDescriptor': fontdescObject,
 }
 
- fontdict.update({
- 'Encoding': { 'Type': Name('Encoding'),
- 'Differences': differencesArray },
- })
+ if fontinfo.encodingfile is not None:
+ enc = dviread.Encoding(fontinfo.encodingfile)
+ differencesArray = [ Name(ch) for ch in enc ]
+ differencesArray = [ 0 ] + differencesArray
+ fontdict.update({
+ 'Encoding': { 'Type': Name('Encoding'),
+ 'Differences': differencesArray },
+ })
 
+ _, _, fullname, familyname, weight, italic_angle, fixed_pitch, \
+ ul_position, ul_thickness = font.get_ps_font_info()
+
 flags = 0
 if fixed_pitch: flags |= 1 << 0 # fixed width
 if 0: flags |= 1 << 1 # TODO: serif
- if 1: flags |= 1 << 2 # TODO: symbolic
+ if 1: flags |= 1 << 2 # TODO: symbolic (most TeX fonts are)
 else: flags |= 1 << 5 # non-symbolic
 if italic_angle: flags |= 1 << 6 # italic
 if 0: flags |= 1 << 16 # TODO: all caps
@@ -598,33 +550,17 @@
 'ItalicAngle': italic_angle,
 'Ascent': font.ascender,
 'Descent': font.descender,
- 'CapHeight': 1000, # default guess if missing from AFM file
- 'XHeight': afmdata.get_xheight(),
+ 'CapHeight': 1000, # TODO: find this out
+ 'XHeight': 500, # TODO: this one too
 'FontFile': fontfileObject,
 'FontFamily': familyname,
+ 'StemV': 50, # TODO 
+ # (see also revision 3874; but not all TeX distros have AFM files!)
 #'FontWeight': a number where 400 = Regular, 700 = Bold
 }
- try:
- descriptor['CapHeight'] = afmdata.get_capheight()
- except KeyError:
- pass
 
- # StemV is obligatory in PDF font descriptors but optional in
- # AFM files. The collection of AFM files in my TeX Live 2007
- # collection has values ranging from 22 to 219, with both
- # median and mode 50, so if the AFM file is silent, I'm
- # guessing 50. -JKS
- StemV = afmdata.get_vertical_stem_width()
- if StemV is None: StemV = 50
- descriptor['StemV'] = StemV
-
- # StemH is entirely optional:
- StemH = afmdata.get_horizontal_stem_width()
- if StemH is not None:
- descriptor['StemH'] = StemH
-
 self.writeObject(fontdictObject, fontdict)
- self.writeObject(widthsObject, widths)
+ self.writeObject(widthsObject, fontinfo.widths)
 self.writeObject(fontdescObject, descriptor)
 
 t1font = type1font.Type1Font(filename)
@@ -1470,11 +1406,13 @@
 oldfont, seq = None, []
 for x1, y1, dvifont, glyph, width in page.text:
 if dvifont != oldfont:
- fontinfo = self.tex_font_mapping(dvifont.texname)
- pdfname = self.file.fontName(fontinfo.filename)
- self.file.fontInfo[pdfname] = Bunch(
- encodingfile=fontinfo.encoding,
- afmfile=fontinfo.afm)
+ psfont = self.tex_font_mapping(dvifont.texname)
+ pdfname = self.file.fontName(psfont.filename)
+ if self.file.fontInfo.get(pdfname, None) is None:
+ self.file.fontInfo[pdfname] = Bunch(
+ encodingfile=psfont.encoding,
+ widths=dvifont.widths,
+ dvifont=dvifont)
 seq += [['font', pdfname, dvifont.size]]
 oldfont = dvifont
 seq += [['text', x1, y1, [chr(glyph)], x1+width]]
Modified: branches/transforms/lib/matplotlib/dviread.py
===================================================================
--- branches/transforms/lib/matplotlib/dviread.py	2007年10月01日 11:44:54 UTC (rev 3905)
+++ branches/transforms/lib/matplotlib/dviread.py	2007年10月01日 11:53:52 UTC (rev 3906)
@@ -84,7 +84,7 @@
 e = 0 # zero depth
 else: # glyph
 x,y,font,g,w = elt
- h = _mul2012(font._scale, font._tfm.height[g])
+ h = _mul2012(font._scale, font._tfm.height[g])
 e = _mul2012(font._scale, font._tfm.depth[g])
 minx = min(minx, x)
 miny = min(miny, y - h)
@@ -380,19 +380,21 @@
 
 class DviFont(object):
 """
- Object that holds a font's texname and size and supports comparison.
+ Object that holds a font's texname and size, supports comparison,
+ and knows the widths of glyphs in the same units as the AFM file.
 There are also internal attributes (for use by dviread.py) that
 are _not_ used for comparison.
 
 The size is in Adobe points (converted from TeX points).
 """
- __slots__ = ('texname', 'size', '_scale', '_vf', '_tfm')
+ __slots__ = ('texname', 'size', 'widths', '_scale', '_vf', '_tfm')
 
 def __init__(self, scale, tfm, texname, vf):
 self._scale, self._tfm, self.texname, self._vf = \
 scale, tfm, texname, vf
- # TODO: would it make more sense to have the size in dpi units?
 self.size = scale * (72.0 / (72.27 * 2**16))
+ self.widths = [ (1000*tfm.width.get(char, 0)) >> 20
+ for char in range(0, max(tfm.width)) ]
 
 def __eq__(self, other):
 return self.__class__ == other.__class__ and \
@@ -402,6 +404,10 @@
 return not self.__eq__(other)
 
 def _width_of(self, char):
+ """
+ Width of char in dvi units. For internal use by dviread.py.
+ """
+
 width = self._tfm.width.get(char, None)
 if width is not None:
 return _mul2012(width, self._scale)
@@ -598,7 +604,6 @@
 fn, enc = result.filename, result.encoding
 if fn is not None and not fn.startswith('/'):
 result.filename = find_tex_file(fn)
- result.afm = find_tex_file(fn[:-4] + '.afm')
 if enc is not None and not enc.startswith('/'):
 result.encoding = find_tex_file(result.encoding)
 return result
@@ -734,6 +739,9 @@
 result = pipe.readline().rstrip()
 pipe.close()
 
+ matplotlib.verbose.report('find_tex_file: %s -> %s' \
+ % (filename, result),
+ 'debug')
 return result
 
 # With multiple text objects per figure (e.g. tick labels) we may end
Modified: branches/transforms/lib/matplotlib/widgets.py
===================================================================
--- branches/transforms/lib/matplotlib/widgets.py	2007年10月01日 11:44:54 UTC (rev 3905)
+++ branches/transforms/lib/matplotlib/widgets.py	2007年10月01日 11:53:52 UTC (rev 3906)
@@ -971,14 +971,14 @@
 print ' endposition : (%f, %f)' % (erelease.xdata, erelease.ydata)
 print ' used button : ', eclick.button
 
- def toggle_Selector(event):
+ def toggle_selector(event):
 print ' Key pressed.'
- if event.key in ['Q', 'q'] and toggle_Selector.RS.active:
+ if event.key in ['Q', 'q'] and toggle_selector.RS.active:
 print ' RectangleSelector deactivated.'
- toggle_Selector.RS.set_active(False)
- if event.key in ['A', 'a'] and not toggle_Selector.RS.active:
+ toggle_selector.RS.set_active(False)
+ if event.key in ['A', 'a'] and not toggle_selector.RS.active:
 print ' RectangleSelector activated.'
- toggle_Selector.RS.set_active(True)
+ toggle_selector.RS.set_active(True)
 
 x = arange(100)/(99.0)
 y = sin(x)
@@ -986,8 +986,8 @@
 ax = subplot(111)
 ax.plot(x,y)
 
- toggle_Selector.RS = RectangleSelector(ax, onselect, drawtype='line')
- connect('key_press_event', toggle_Selector)
+ toggle_selector.RS = RectangleSelector(ax, onselect, drawtype='line')
+ connect('key_press_event', toggle_selector)
 show()
 """
 def __init__(self, ax, onselect, drawtype='box',
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
From: <md...@us...> - 2007年10月03日 12:50:11
Revision: 3908
 http://matplotlib.svn.sourceforge.net/matplotlib/?rev=3908&view=rev
Author: mdboom
Date: 2007年10月03日 05:50:04 -0700 (2007年10月03日)
Log Message:
-----------
Lots of progress on Polar transform refactoring. Added point_in_path algorithm.
Modified Paths:
--------------
 branches/transforms/lib/matplotlib/artist.py
 branches/transforms/lib/matplotlib/axes.py
 branches/transforms/lib/matplotlib/axis.py
 branches/transforms/lib/matplotlib/backend_bases.py
 branches/transforms/lib/matplotlib/cbook.py
 branches/transforms/lib/matplotlib/figure.py
 branches/transforms/lib/matplotlib/patches.py
 branches/transforms/lib/matplotlib/path.py
 branches/transforms/lib/matplotlib/scale.py
 branches/transforms/lib/matplotlib/text.py
 branches/transforms/lib/matplotlib/ticker.py
 branches/transforms/lib/matplotlib/transforms.py
 branches/transforms/setup.py
 branches/transforms/src/_backend_agg.cpp
 branches/transforms/src/_backend_agg.h
Added Paths:
-----------
 branches/transforms/lib/matplotlib/projections/
 branches/transforms/lib/matplotlib/projections/polar.py
Removed Paths:
-------------
 branches/transforms/lib/matplotlib/pbox.py
Modified: branches/transforms/lib/matplotlib/artist.py
===================================================================
--- branches/transforms/lib/matplotlib/artist.py	2007年10月02日 08:30:29 UTC (rev 3907)
+++ branches/transforms/lib/matplotlib/artist.py	2007年10月03日 12:50:04 UTC (rev 3908)
@@ -1,7 +1,8 @@
 from __future__ import division
 import sys, re
 from cbook import iterable, flatten
-from transforms import Affine2D
+from transforms import Affine2D, Bbox, IdentityTransform, TransformedBbox, \
+ TransformedPath
 import matplotlib.units as units
 
 ## Note, matplotlib artists use the doc strings for set and get
@@ -145,7 +146,7 @@
 def get_transform(self):
 'return the Transformation instance used by this artist'
 if self._transform is None:
- self._transform = Affine2D()
+ self._transform = IdentityTransform()
 return self._transform
 
 def hitlist(self,event):
@@ -284,17 +285,29 @@
 self._clipon = clipbox is not None or self._clippath is not None
 self.pchanged()
 
- def set_clip_path(self, path):
+ def set_clip_path(self, path, transform=None):
 """
 Set the artist's clip path
 
- ACCEPTS: an agg.path_storage instance
+ ACCEPTS: a Path instance and a Transform instance, or a Patch instance
 """
- self._clippath = path
+ from patches import Patch, Rectangle
+ if transform is None:
+ if isinstance(path, Rectangle):
+ self.clipbox = TransformedBbox(Bbox.unit(), path.get_transform())
+ elif isinstance(path, Patch):
+ self._clippath = TransformedPath(
+ path.get_path(),
+ path.get_transform())
+ elif path is None:
+ self._clippath = None
+ else:
+ raise TypeError("Invalid arguments to set_clip_path")
+ else:
+ self._clippath = TransformedPath(path, transform)
 self._clipon = self.clipbox is not None or path is not None
 self.pchanged()
 
-
 def get_alpha(self):
 """
 Return the alpha value used for blending - not supported on all
@@ -431,6 +444,7 @@
 self._alpha = other._alpha
 self.clipbox = other.clipbox
 self._clipon = other._clipon
+ self._clippath = other._clippath
 self._lod = other._lod
 self._label = other._label
 self.pchanged()
Modified: branches/transforms/lib/matplotlib/axes.py
===================================================================
--- branches/transforms/lib/matplotlib/axes.py	2007年10月02日 08:30:29 UTC (rev 3907)
+++ branches/transforms/lib/matplotlib/axes.py	2007年10月03日 12:50:04 UTC (rev 3908)
@@ -1,5 +1,5 @@
 from __future__ import division, generators
-import math, sys, warnings, copy
+import math, sys, warnings, copy, new
 
 import numpy as npy
 
@@ -24,7 +24,6 @@
 from matplotlib import cm
 from matplotlib import patches as mpatches
 from matplotlib import path as mpath
-from matplotlib import pbox as mpbox
 from matplotlib import quiver as mquiver
 from matplotlib import scale as mscale
 from matplotlib import table as mtable
@@ -428,15 +427,8 @@
 
 
 """
-
- # MGDTODO
-# scaled = {mtrans.IDENTITY : 'linear',
-# mtrans.LOG10 : 'log',
-# }
- scaled = {0 : 'linear',
- 1 : 'log',
- }
-
+ name = "rectilinear"
+ 
 _shared_x_axes = cbook.Grouper()
 _shared_y_axes = cbook.Grouper()
 
@@ -474,16 +466,16 @@
 visible: a boolean - whether the axes is visible
 xlabel: the xlabel
 xlim: (xmin, xmax) view limits
- xscale: ['log' | 'linear' ]
+ xscale: [%(scale)s]
 xticklabels: sequence of strings
 xticks: sequence of floats
 ylabel: the ylabel strings
 ylim: (ymin, ymax) view limits
- yscale: ['log' | 'linear']
+ yscale: [%(scale)s]
 yticklabels: sequence of strings
 yticks: sequence of floats
 
- """
+ """ % {'scale': ' | '.join([repr(x) for x in mscale.get_scale_names()])}
 martist.Artist.__init__(self)
 self._position = mtransforms.Bbox.from_lbwh(*rect)
 self._originalPosition = copy.deepcopy(self._position)
@@ -637,6 +629,10 @@
 # It is assumed that this part will have non-linear components
 self.transScale = mtransforms.TransformWrapper(mtransforms.IdentityTransform())
 
+ self._set_transData()
+
+ # MGDTODO: Rename this method
+ def _set_transData(self):
 # A (possibly non-linear) projection on the (already scaled) data
 self.transProjection = mtransforms.IdentityTransform()
 
@@ -647,7 +643,33 @@
 
 self.transData = self.transScale + self.transProjection + self.transLimits + self.transAxes
 
+ self._xaxis_transform = mtransforms.blended_transform_factory(
+ self.axes.transData, self.axes.transAxes)
+ self._yaxis_transform = mtransforms.blended_transform_factory(
+ self.axes.transAxes, self.axes.transData)
 
+ def get_xaxis_transform(self):
+ return self._xaxis_transform
+
+ def get_xaxis_text1_transform(self, pad_pixels):
+ return (self._xaxis_transform +
+ mtransforms.Affine2D().translate(0, -1 * pad_pixels))
+
+ def get_xaxis_text2_transform(self, pad_pixels):
+ return (self._xaxis_transform +
+ mtransforms.Affine2D().translate(0, pad_pixels))
+
+ def get_yaxis_transform(self):
+ return self._yaxis_transform
+
+ def get_yaxis_text1_transform(self, pad_pixels):
+ return (self._yaxis_transform +
+ mtransforms.Affine2D().translate(-1 * pad_pixels, 0))
+
+ def get_yaxis_text2_transform(self, pad_pixels):
+ return (self._yaxis_transform +
+ mtransforms.Affine2D().translate(pad_pixels, 0))
+ 
 def _update_transScale(self):
 self.transScale.set(
 mtransforms.blended_transform_factory(
@@ -691,6 +713,9 @@
 a.set_transform(self.transData)
 a.axes = self
 
+ def get_axes_patch(self):
+ return mpatches.Rectangle((0.0, 0.0), 1.0, 1.0)
+ 
 def cla(self):
 'Clear the current axes'
 
@@ -734,24 +759,26 @@
 self.title.set_clip_box(None)
 
 self._set_artist_props(self.title)
-
- self.axesPatch = mpatches.Rectangle(
- xy=(0,0), width=1, height=1,
- facecolor=self._axisbg,
- edgecolor=rcParams['axes.edgecolor'],
- )
+ 
+ self.axesPatch = self.get_axes_patch()
 self.axesPatch.set_figure(self.figure)
- self.axesPatch.set_transform(self.transAxes)
+ self.axesPatch.set_facecolor(self._axisbg)
+ self.axesPatch.set_edgecolor(rcParams['axes.edgecolor'])
 self.axesPatch.set_linewidth(rcParams['axes.linewidth'])
- # MGDTODO: What is axesFrame for? We already have axesPatch
- self.axesFrame = mlines.Line2D((0,1,1,0,0), (0,0,1,1,0),
- linewidth=rcParams['axes.linewidth'],
- color=rcParams['axes.edgecolor'],
- figure=self.figure)
+ self.axesPatch.set_transform(self.transAxes)
+
+ self.axesFrame = self.get_axes_patch()
+ self.axesFrame.set_figure(self.figure)
+ self.axesFrame.set_facecolor(None)
+ self.axesFrame.set_edgecolor(rcParams['axes.edgecolor'])
+ self.axesFrame.set_linewidth(rcParams['axes.linewidth'])
 self.axesFrame.set_transform(self.transAxes)
 self.axesFrame.set_zorder(2.5)
 self.axison = True
 
+ self.xaxis.set_clip_path(self.axesPatch)
+ self.yaxis.set_clip_path(self.axesPatch)
+
 def clear(self):
 'clear the axes'
 self.cla()
@@ -838,19 +865,23 @@
 """
 ACCEPTS: ['C', 'SW', 'S', 'SE', 'E', 'NE', 'N', 'NW', 'W']
 """
- if anchor in mpbox.PBox.coefs.keys() or len(anchor) == 2:
+ if anchor in mtransforms.Bbox.coefs.keys() or len(anchor) == 2:
 self._anchor = anchor
 else:
 raise ValueError('argument must be among %s' %
- ', '.join(PBox.coefs.keys()))
+ ', '.join(mtransforms.BBox.coefs.keys()))
 
-
- def apply_aspect(self, data_ratio = None):
+ def get_data_ratio(self):
+ xmin,xmax = self.get_xlim()
+ xsize = max(math.fabs(xmax-xmin), 1e-30)
+ ymin,ymax = self.get_ylim()
+ ysize = max(math.fabs(ymax-ymin), 1e-30)
+ return ysize/xsize
+ 
+ def apply_aspect(self):
 '''
 Use self._aspect and self._adjustable to modify the
 axes box or the view limits.
- The data_ratio kwarg is set to 1 for polar axes. It is
- used only when _adjustable is 'box'.
 '''
 
 if self._aspect == 'auto':
@@ -869,18 +900,11 @@
 
 figW,figH = self.get_figure().get_size_inches()
 fig_aspect = figH/figW
- #print 'figW, figH, fig_aspect', figW, figH, fig_aspect
- xmin,xmax = self.get_xlim()
- xsize = max(math.fabs(xmax-xmin), 1e-30)
- ymin,ymax = self.get_ylim()
- ysize = max(math.fabs(ymax-ymin), 1e-30)
 if self._adjustable == 'box':
- if data_ratio is None:
- data_ratio = ysize/xsize
- box_aspect = A * data_ratio
- pb = mpbox.PBox(self._originalPosition)
- pb1 = pb.shrink_to_aspect(box_aspect, fig_aspect)
- self.set_position(pb1.anchor(self._anchor), 'active')
+ box_aspect = A * self.get_data_ratio()
+ pb = self._originalPosition.frozen()
+ pb1 = pb.shrunk_to_aspect(box_aspect, pb, fig_aspect)
+ self.set_position(pb1.anchored(self._anchor, pb), 'active')
 return
 
 
@@ -1079,7 +1103,7 @@
 collection.set_label('collection%d'%len(self.collections))
 self.collections.append(collection)
 self._set_artist_props(collection)
- collection.set_clip_box(self.bbox)
+ collection.set_clip_path(self.axesPatch)
 if autolim:
 self.update_datalim(collection.get_verts(self.transData))
 collection._remove_method = lambda h: self.collections.remove(h)
@@ -1087,7 +1111,7 @@
 def add_line(self, line):
 'Add a line to the list of plot lines'
 self._set_artist_props(line)
- line.set_clip_box(self.bbox)
+ line.set_clip_path(self.axesPatch)
 
 self._update_line_limits(line)
 if not line.get_label():
@@ -1107,7 +1131,7 @@
 """
 
 self._set_artist_props(p)
- p.set_clip_box(self.bbox)
+ p.set_clip_path(self.axesPatch)
 self._update_patch_limits(p)
 self.patches.append(p)
 p._remove_method = lambda h: self.patches.remove(h)
@@ -1115,7 +1139,7 @@
 def _update_patch_limits(self, p):
 'update the datalimits for patch p'
 xys = self._get_verts_in_data_coords(
- p.get_transform(), p.get_verts())
+ p.get_transform(), p.get_path().vertices)
 self.update_datalim(xys)
 
 
@@ -1160,8 +1184,8 @@
 # display and then back to data to get it in data units
 #xys = trans.seq_xy_tups(xys)
 #return [ self.transData.inverse_xy_tup(xy) for xy in xys]
- xys = trans(npy.asarray(xys))
- return self.transData.inverted()(xys)
+ xys = trans.transform(npy.asarray(xys))
+ return self.transData.inverted().transform(xys)
 
 def _process_unit_info(self, xdata=None, ydata=None, kwargs=None):
 'look for unit kwargs and update the axis instances as necessary'
@@ -1189,9 +1213,9 @@
 #print '\tkw setting yunits', yunits
 self.yaxis.set_units(yunits)
 
- def in_axes(self, xwin, ywin):
+ def in_axes(self, mouseevent):
 'return True is the point xwin, ywin (display coords) are in the Axes'
- return self.bbox.contains(xwin, ywin)
+ return self.axesPatch.contains(mouseevent)[0]
 
 def get_autoscale_on(self):
 """
@@ -1207,7 +1231,6 @@
 """
 self._autoscaleon = b
 
-
 def autoscale_view(self, tight=False, scalex=True, scaley=True):
 """
 autoscale the view limits using the data limits. You can
@@ -1239,8 +1262,8 @@
 if yl[1] < yl[0]:
 YL = YL[::-1]
 self.set_ylim(YL)
- #### Drawing
 
+ #### Drawing
 def draw(self, renderer=None, inframe=False):
 "Draw everything (plot lines, axes, labels)"
 	if renderer is None:
@@ -1252,7 +1275,9 @@
 renderer.open_group('axes')
 self.apply_aspect()
 
- if self.axison and self._frameon: self.axesPatch.draw(renderer)
+ if self.axison and self._frameon:
+ self.axesPatch.draw(renderer)
+ 
 artists = []
 
 if len(self.images)<=1 or renderer.option_image_nocomposite():
@@ -1262,7 +1287,6 @@
 # make a composite image blending alpha
 # list of (mimage.Image, ox, oy)
 
-
 mag = renderer.get_image_magnification()
 ims = [(im.make_image(mag),0,0)
 for im in self.images if im.get_visible()]
@@ -1277,8 +1301,6 @@
 # respect z-order for now
 renderer.draw_image(l, b, im, self.bbox)
 
-
-
 artists.extend(self.collections)
 artists.extend(self.patches)
 artists.extend(self.lines)
@@ -1517,14 +1539,15 @@
 return xmin, xmax
 
 def get_xscale(self):
- 'return the xaxis scale string: log or linear'
+ 'return the xaxis scale string: %s' % (
+ ", ".join(mscale.get_scale_names()))
 	return self.xaxis.get_scale()
 
 def set_xscale(self, value, **kwargs):
 """
- SET_XSCALE(value, basex=10, subsx=None)
+ SET_XSCALE(value)
 
- Set the xscaling: 'log' or 'linear'
+ Set the xscaling: %(scale)s
 
 If value is 'log', the additional kwargs have the following meaning
 
@@ -1536,8 +1559,8 @@
 put minor ticks on 1,2,5,11,12,15,21, ....To turn off
 minor ticking, set subsx=[]
 
- ACCEPTS: ['log' | 'linear' ]
- """
+ ACCEPTS: [%(scale)s]
+ """ % {'scale': ' | '.join([repr(x) for x in mscale.get_scale_names()])}
 self.xaxis.set_scale(value, **kwargs)
 self._update_transScale()
 
@@ -1610,11 +1633,6 @@
 if ymin is None: ymin = old_ymin
 if ymax is None: ymax = old_ymax
 
-	# MGDTODO
-# if (self.transData.get_funcy().get_type()==mtrans.LOG10
-# and min(ymin, ymax)<=0):
-# raise ValueError('Cannot set nonpositive limits with log transform')
-
 ymin, ymax = mtransforms.nonsingular(ymin, ymax, increasing=False)
 	self.viewLim.intervaly = (ymin, ymax)
 if emit:
@@ -1627,14 +1645,15 @@
 return ymin, ymax
 
 def get_yscale(self):
- 'return the yaxis scale string: log or linear'
+ 'return the xaxis scale string: %s' % (
+ ", ".join(mscale.get_scale_names()))
 return self.yaxis.get_scale()
 
 def set_yscale(self, value, **kwargs):
 """
 SET_YSCALE(value, basey=10, subsy=None)
 
- Set the yscaling: 'log' or 'linear'
+ Set the yscaling: %(scale)s
 
 If value is 'log', the additional kwargs have the following meaning
 
@@ -1646,8 +1665,8 @@
 put minor ticks on 1,2,5,11,12,15, 21, ....To turn off
 minor ticking, set subsy=[]
 
- ACCEPTS: ['log' | 'linear']
- """
+ ACCEPTS: %(scale)s
+ """ % {'scale': ' | '.join([repr(x) for x in mscale.get_scale_names()])}
 self.yaxis.set_scale(value, **kwargs)
 self._update_transScale()
 
@@ -1682,14 +1701,6 @@
 return self.yaxis.set_ticklabels(labels, fontdict, **kwargs)
 set_yticklabels.__doc__ = cbook.dedent(set_yticklabels.__doc__) % martist.kwdocd
 
- def toggle_log_lineary(self):
- 'toggle between log and linear on the y axis'
-	# MGDTODO
-# funcy = self.transData.get_funcy().get_type()
-# if funcy==mtrans.LOG10: self.set_yscale('linear')
-# elif funcy==mtrans.IDENTITY: self.set_yscale('log')
-	pass
-
 def xaxis_date(self, tz=None):
 """Sets up x-axis ticks and labels that treat the x data as dates.
 
@@ -1748,12 +1759,12 @@
 
 def format_coord(self, x, y):
 'return a format string formatting the x, y coord'
-
+ if x is None or y is None:
+ return ''
 xs = self.format_xdata(x)
 ys = self.format_ydata(y)
 return 'x=%s, y=%s'%(xs,ys)
-
-
+ 
 #### Interactive manipulation
 
 def get_navigate(self):
@@ -1784,17 +1795,40 @@
 """
 self._navigate_mode = b
 
- def drag_pan(self, button, x, y, startx, starty, start_lim, start_trans):
+ def drag_pan(self, button, key, startx, starty, dx, dy,
+ start_lim, start_trans):
+ def format_deltas(key, dx, dy):
+ if key=='control':
+ if(abs(dx)>abs(dy)):
+ dy = dx
+ else:
+ dx = dy
+ elif key=='x':
+ dy = 0
+ elif key=='y':
+ dx = 0
+ elif key=='shift':
+ if 2*abs(dx) < abs(dy):
+ dx=0
+ elif 2*abs(dy) < abs(dx):
+ dy=0
+ elif(abs(dx)>abs(dy)):
+ dy=dy/abs(dy)*abs(dx)
+ else:
+ dx=dx/abs(dx)*abs(dy)
+ return (dx,dy)
+
 if button == 1:
 inverse = start_trans.inverted()
- dx = startx - x
- dy = starty - y
- result = self.bbox.frozen().translated(dx, dy).transformed(inverse)
+ dx, dy = format_deltas(key, dx, dy)
+ result = self.bbox.frozen().translated(-dx, -dy).transformed(inverse)
 elif button == 3:
 try:
+ # MGDTODO: This is broken with log scales
 inverse = start_trans.inverted()
- dx = (startx - x) / float(self.bbox.width)
- dy = (starty - y) / float(self.bbox.height)
+ dx, dy = format_deltas(key, dx, dy)
+ dx = -dx / float(self.bbox.width)
+ dy = -dy / float(self.bbox.height)
 xmin, ymin, xmax, ymax = start_lim.lbrt
 
 alpha = npy.power(10.0, (dx, dy))
@@ -1806,7 +1840,6 @@
 warnings.warn('Overflow while panning')
 return
 
- # MGDTODO: Could we do this with a single set_lim?
 self.set_xlim(*result.intervalx)
 self.set_ylim(*result.intervaly)
 
@@ -1880,7 +1913,7 @@
 """
 if callable(self._contains): return self._contains(self,mouseevent)
 
- inside = self.bbox.contains(mouseevent.x,mouseevent.y)
+ inside = self.axesPatch.contains(mouseevent.x, mouseevent.y)
 return inside,{}
 
 def pick(self,*args):
@@ -2100,7 +2133,7 @@
 
 
 #if t.get_clip_on(): t.set_clip_box(self.bbox)
- if kwargs.has_key('clip_on'): t.set_clip_box(self.bbox)
+ if kwargs.has_key('clip_on'): t.set_clip_path(self.axesPatch)
 return t
 text.__doc__ = cbook.dedent(text.__doc__) % martist.kwdocd
 
@@ -2118,7 +2151,7 @@
 a = mtext.Annotation(*args, **kwargs)
 a.set_transform(mtransforms.Affine2D())
 self._set_artist_props(a)
- if kwargs.has_key('clip_on'): a.set_clip_box(self.bbox)
+ if kwargs.has_key('clip_on'): a.set_clip_path(self.axesPatch)
 self.texts.append(a)
 return a
 annotate.__doc__ = cbook.dedent(annotate.__doc__) % martist.kwdocd
@@ -5056,7 +5089,7 @@
 Subplot(211) # 2 rows, 1 column, first (upper) plot
 """
 
- def __init__(self, fig, *args):
+ def __init__(self, fig, *args, **kwargs):
 """
 fig is a figure instance
 
@@ -5087,6 +5120,10 @@
 
 self.update_params()
 
+ # _axes_class is set in the subplot_class_factory
+ self._axes_class.__init__(self, fig, [self.figLeft, self.figBottom,
+ self.figW, self.figH], **kwargs)
+ 
 def get_geometry(self):
 'get the subplot geometry, eg 2,2,3'
 return self._rows, self._cols, self._num+1
@@ -5176,36 +5213,18 @@
 for label in self.get_yticklabels():
 label.set_visible(firstcol)
 
-class Subplot(SubplotBase, Axes):
- """
- Emulate matlab's(TM) subplot command, creating axes with
+def subplot_class_factory(axes_class=None):
+ # MGDTODO: This is a little bit strange to make a new class on the
+ # fly like this, but it keeps things relatively similar to how they
+ # were before
+ new_class = new.classobj("%sSubplot" % (axes_class.__name__),
+ (SubplotBase, axes_class),
+ {'_axes_class': axes_class})
+ return new_class
 
- Subplot(numRows, numCols, plotNum)
 
- where plotNum=1 is the first plot number and increasing plotNums
- fill rows first. max(plotNum)==numRows*numCols
-
- You can leave out the commas if numRows<=numCols<=plotNum<10, as
- in
-
- Subplot(211) # 2 rows, 1 column, first (upper) plot
- """
- def __str__(self):
- return "Subplot(%f,%f,%f,%f)" % (self.bbox.bounds)
-
- def __init__(self, fig, *args, **kwargs):
- """
- See Axes base class documentation for args and kwargs
- """
- SubplotBase.__init__(self, fig, *args)
- Axes.__init__(self, fig, [self.figLeft, self.figBottom,
- self.figW, self.figH], **kwargs)
-
-
-
 class PolarAxes(Axes):
 """
-
 Make a PolarAxes. The rectangular bounding box of the axes is given by
 
 
@@ -5644,11 +5663,6 @@
 'return the yaxis scale string'
 return 'polar'
 
- def toggle_log_lineary(self):
- 'toggle between log and linear axes ignored for polar'
- pass
-
-
 def table(self, *args, **kwargs):
 """
 TABLE(*args, **kwargs)
@@ -5679,255 +5693,9 @@
 PolarAxes.__init__(
 self, fig,
 [self.figLeft, self.figBottom, self.figW, self.figH], **kwargs)
-
-######################################################################
-# New Polar Axes
 
-class PolarAxes(Axes):
- class PolarTransform(mtransforms.Transform):
- input_dims = 2
- output_dims = 2
- is_separable = False
-
- def transform(self, tr):
- xy = npy.zeros(tr.shape, npy.float_)
- t = tr[:, 0:1]
- r = tr[:, 1:2]
- x = xy[:, 0:1]
- y = xy[:, 1:2]
- x += r * npy.cos(t)
- y += r * npy.sin(t)
- return xy
- transform_non_affine = transform
-
- def interpolate(self, a, steps):
- steps = npy.floor(steps)
- new_length = ((len(a) - 1) * steps) + 1
- new_shape = list(a.shape)
- new_shape[0] = new_length
- result = npy.zeros(new_shape, a.dtype)
-
- result[0] = a[0]
- a0 = a[0:-1]
- a1 = a[1: ]
- delta = ((a1 - a0) / steps)
- 
- for i in range(1, int(steps)+1):
- result[i::steps] = delta * i + a0
-
- return result
- 
-# def transform_path(self, path):
-# twopi = 2.0 * npy.pi
-# halfpi = 0.5 * npy.pi
- 
-# vertices = path.vertices
-# t0 = vertices[0:-1, 0]
-# t1 = vertices[1: , 0]
-# td = npy.where(t1 > t0, t1 - t0, twopi - (t0 - t1))
-# maxtd = td.max()
-# interpolate = npy.ceil(maxtd / halfpi)
-# if interpolate > 1.0:
-# vertices = self.interpolate(vertices, interpolate)
-
-# vertices = self.transform(vertices)
-
-# result = npy.zeros((len(vertices) * 3 - 2, 2), npy.float_)
-# codes = mpath.Path.CURVE4 * npy.ones((len(vertices) * 3 - 2, ), mpath.Path.code_type)
-# result[0] = vertices[0]
-# codes[0] = mpath.Path.MOVETO
-
-# kappa = 4.0 * ((npy.sqrt(2.0) - 1.0) / 3.0)
-# kappa = 0.5
- 
-# p0 = vertices[0:-1]
-# p1 = vertices[1: ]
-
-# x0 = p0[:, 0:1]
-# y0 = p0[:, 1: ]
-# b0 = ((y0 - x0) - y0) / ((x0 + y0) - x0)
-# a0 = y0 - b0*x0
-
-# x1 = p1[:, 0:1]
-# y1 = p1[:, 1: ]
-# b1 = ((y1 - x1) - y1) / ((x1 + y1) - x1)
-# a1 = y1 - b1*x1
-
-# x = -(a0-a1) / (b0-b1)
-# y = a0 + b0*x
-
-# xk = (x - x0) * kappa + x0
-# yk = (y - y0) * kappa + y0
-
-# result[1::3, 0:1] = xk
-# result[1::3, 1: ] = yk
-
-# xk = (x - x1) * kappa + x1
-# yk = (y - y1) * kappa + y1
-
-# result[2::3, 0:1] = xk
-# result[2::3, 1: ] = yk
- 
-# result[3::3] = p1
-
-# print vertices[-2:]
-# print result[-2:]
- 
-# return mpath.Path(result, codes)
- 
-# twopi = 2.0 * npy.pi
-# halfpi = 0.5 * npy.pi
- 
-# vertices = path.vertices
-# t0 = vertices[0:-1, 0]
-# t1 = vertices[1: , 0]
-# td = npy.where(t1 > t0, t1 - t0, twopi - (t0 - t1))
-# maxtd = td.max()
-# interpolate = npy.ceil(maxtd / halfpi)
-
-# print "interpolate", interpolate
-# if interpolate > 1.0:
-# vertices = self.interpolate(vertices, interpolate)
- 
-# result = npy.zeros((len(vertices) * 3 - 2, 2), npy.float_)
-# codes = mpath.Path.CURVE4 * npy.ones((len(vertices) * 3 - 2, ), mpath.Path.code_type)
-# result[0] = vertices[0]
-# codes[0] = mpath.Path.MOVETO
-
-# kappa = 4.0 * ((npy.sqrt(2.0) - 1.0) / 3.0)
-# tkappa = npy.arctan(kappa)
-# hyp_kappa = npy.sqrt(kappa*kappa + 1.0)
-
-# t0 = vertices[0:-1, 0]
-# t1 = vertices[1: , 0]
-# r0 = vertices[0:-1, 1]
-# r1 = vertices[1: , 1]
-
-# td = npy.where(t1 > t0, t1 - t0, twopi - (t0 - t1))
-# td_scaled = td / (npy.pi * 0.5)
-# rd = r1 - r0
-# r0kappa = r0 * kappa * td_scaled
-# r1kappa = r1 * kappa * td_scaled
-# ravg_kappa = ((r1 + r0) / 2.0) * kappa * td_scaled
-
-# result[1::3, 0] = t0 + (tkappa * td_scaled)
-# result[1::3, 1] = r0*hyp_kappa
-# # result[1::3, 1] = r0 / npy.cos(tkappa * td_scaled) # npy.sqrt(r0*r0 + ravg_kappa*ravg_kappa)
-
-# result[2::3, 0] = t1 - (tkappa * td_scaled)
-# result[2::3, 1] = r1*hyp_kappa
-# # result[2::3, 1] = r1 / npy.cos(tkappa * td_scaled) # npy.sqrt(r1*r1 + ravg_kappa*ravg_kappa)
- 
-# result[3::3, 0] = t1
-# result[3::3, 1] = r1
-
-# print vertices[:6], result[:6], t0[:6], t1[:6], td[:6], td_scaled[:6], tkappa
-# result = self.transform(result)
-# return mpath.Path(result, codes)
-# transform_path_non_affine = transform_path
-
- def inverted(self):
- return PolarAxes.InvertedPolarTransform()
-
- class PolarAffine(mtransforms.Affine2DBase):
- def __init__(self, limits):
- mtransforms.Affine2DBase.__init__(self)
- self._limits = limits
- self.set_children(limits)
- self._mtx = None
-
- def get_matrix(self):
- if self._invalid:
- xmin, ymin, xmax, ymax = self._limits.lbrt
- affine = mtransforms.Affine2D().rotate(xmin).scale(0.5 / ymax).translate(0.5, 0.5)
- self._mtx = affine.get_matrix()
- self._inverted = None
- self._invalid = 0
- return self._mtx
- 
- class InvertedPolarTransform(mtransforms.Transform):
- input_dims = 2
- output_dims = 2
- is_separable = False
-
- def transform(self, xy):
- x = xy[:, 0:1]
- y = xy[:, 1:]
- r = npy.sqrt(x*x + y*y)
- theta = npy.arccos(x / r)
- theta = npy.where(y < 0, 2 * npy.pi - theta, theta)
- return npy.concatenate((theta, r), 1)
-
- def inverted(self):
- return PolarAxes.PolarTransform()
- 
- def _set_lim_and_transforms(self):
- """
- set the dataLim and viewLim BBox attributes and the
- transData and transAxes Transformation attributes
- """
-	self.dataLim = mtransforms.Bbox.unit()
- self.viewLim = mtransforms.Bbox.unit()
- self.transAxes = mtransforms.BboxTransform(
- mtransforms.Bbox.unit(), self.bbox)
-
- # Transforms the x and y axis separately by a scale factor
- # It is assumed that this part will have non-linear components
- self.transScale = mtransforms.TransformWrapper(mtransforms.IdentityTransform())
-
- # A (possibly non-linear) projection on the (already scaled) data
- self.transProjection = self.PolarTransform()
-
- # An affine transformation on the data, generally to limit the
- # range of the axes
- self.transProjectionAffine = self.PolarAffine(self.viewLim)
- 
- self.transData = self.transScale + self.transProjection + \
- self.transProjectionAffine + self.transAxes
-
- def drag_pan(self, button, x, y, startx, starty, start_lim, start_trans):
- if button == 1:
- inverse = start_trans.inverted()
- startt, startr = inverse.transform_point((startx, starty))
- t, r = inverse.transform_point((x, y))
-
- scale = r / startr
- self.set_ylim(start_lim.ymin, start_lim.ymax / scale)
-
- dt0 = t - startt
- dt1 = startt - t
- if abs(dt1) < abs(dt0):
- dt = abs(dt1) * sign(dt0) * -1.0
- else:
- dt = dt0 * -1.0
- self.set_xlim(start_lim.xmin - dt, start_lim.xmin - dt + npy.pi*2.0)
- 
- def set_rmax(self, rmax):
- self.viewLim.maxy = rmax
- 
-class PolarSubplot(SubplotBase, PolarAxes):
- """
- Create a polar subplot with
-
- PolarSubplot(numRows, numCols, plotNum)
-
- where plotNum=1 is the first plot number and increasing plotNums
- fill rows first. max(plotNum)==numRows*numCols
-
- You can leave out the commas if numRows<=numCols<=plotNum<10, as
- in
-
- Subplot(211) # 2 rows, 1 column, first (upper) plot
- """
- def __str__(self):
- return "PolarSubplot(%gx%g)"%(self.figW,self.figH)
- def __init__(self, fig, *args, **kwargs):
- SubplotBase.__init__(self, fig, *args)
- PolarAxes.__init__(
- self, fig,
- [self.figLeft, self.figBottom, self.figW, self.figH], **kwargs)
- 
 martist.kwdocd['Axes'] = martist.kwdocd['Subplot'] = martist.kwdoc(Axes)
+
 """
 # this is some discarded code I was using to find the minimum positive
 # data point for some log scaling fixes. I realized there was a
Modified: branches/transforms/lib/matplotlib/axis.py
===================================================================
--- branches/transforms/lib/matplotlib/axis.py	2007年10月02日 08:30:29 UTC (rev 3907)
+++ branches/transforms/lib/matplotlib/axis.py	2007年10月03日 12:50:04 UTC (rev 3908)
@@ -18,12 +18,11 @@
 from font_manager import FontProperties
 from text import Text, TextWithDash, _process_text_args
 from transforms import Affine2D, Bbox, blended_transform_factory, interval_contains, \
- interval_contains_open, IntervalTransform
+ interval_contains_open, IntervalTransform, IdentityTransform
 from patches import bbox_artist
 from scale import scale_factory
 
 import matplotlib.units as units
-#import pdb
 
 
 class Tick(Artist):
@@ -112,6 +111,12 @@
 children = [self.tick1line, self.tick2line, self.gridline, self.label1, self.label2]
 return children
 
+ def set_clip_path(self, clippath, transform=None):
+ Artist.set_clip_path(self, clippath, transform)
+ self.tick1line.set_clip_path(clippath, transform)
+ self.tick2line.set_clip_path(clippath, transform)
+ self.gridline.set_clip_path(clippath, transform)
+ 
 def contains(self, mouseevent):
 """Test whether the mouse event occured in the Tick marks.
 
@@ -164,9 +169,12 @@
 midPoint = interval_contains_open(self.get_view_interval(), self.get_loc() )
 
 if midPoint:
- if self.gridOn: self.gridline.draw(renderer)
- if self.tick1On: self.tick1line.draw(renderer)
- if self.tick2On: self.tick2line.draw(renderer)
+ if self.gridOn:
+ self.gridline.draw(renderer)
+ if self.tick1On:
+ self.tick1line.draw(renderer)
+ if self.tick2On:
+ self.tick2line.draw(renderer)
 
 if self.label1On: self.label1.draw(renderer)
 if self.label2On: self.label2.draw(renderer)
@@ -213,8 +221,10 @@
 'return the view Interval instance for the axis tjis tick is ticking'
 raise NotImplementedError('Derived must override')
 
+ def set_view_interval(self, vmin, vmax, ignore=False):
+ raise NotImplementedError('Derived must override')
 
-
+ 
 class XTick(Tick):
 """
 Contains all the Artists needed to make an x tick - the tick line,
@@ -237,12 +247,7 @@
 xaxis=True,
 )
 
-	trans = blended_transform_factory(
-	 self.axes.transData, self.axes.transAxes)
- #offset the text downward with a post transformation
-	trans = trans + Affine2D().translate(0, -1 * self._padPixels)
- t.set_transform(trans)
-
+ t.set_transform(self.axes.get_xaxis_text1_transform(self._padPixels))
 self._set_artist_props(t)
 return t
 
@@ -262,11 +267,7 @@
 horizontalalignment='center',
 )
 
-	trans = blended_transform_factory(
-	 self.axes.transData, self.axes.transAxes)
- # offset the text upward with a post transformation
- trans = trans + Affine2D().translate(0, self._padPixels)
- t.set_transform( trans )
+ t.set_transform(self.axes.get_xaxis_text2_transform(self._padPixels))
 self._set_artist_props(t)
 return t
 
@@ -280,8 +281,7 @@
 marker = self._xtickmarkers[0],
 markersize=self._size,
 )
- l.set_transform(blended_transform_factory(
-		self.axes.transData, self.axes.transAxes) )
+ l.set_transform(self.axes.get_xaxis_transform())
 self._set_artist_props(l)
 return l
 
@@ -296,24 +296,20 @@
 markersize=self._size,
 )
 
- l.set_transform(blended_transform_factory(
-		self.axes.transData, self.axes.transAxes) )
+ l.set_transform(self.axes.get_xaxis_transform())
 self._set_artist_props(l)
 return l
 
 def _get_gridline(self, loc):
 'Get the default line2D instance'
 # x in data coords, y in axes coords
- l = Line2D( xdata=(loc, loc), ydata=(0, 1),
- color=rcParams['grid.color'],
- linestyle=rcParams['grid.linestyle'],
- linewidth=rcParams['grid.linewidth'],
- antialiased=False,
- )
- l.set_transform(
-	 blended_transform_factory(
-		self.axes.transData, self.axes.transAxes))
- l.set_clip_box(self.axes.bbox)
+ l = Line2D(xdata=(loc, loc), ydata=(0, 1.0),
+ color=rcParams['grid.color'],
+ linestyle=rcParams['grid.linestyle'],
+ linewidth=rcParams['grid.linewidth'],
+ antialiased=False,
+ )
+ l.set_transform(self.axes.get_xaxis_transform())
 self._set_artist_props(l)
 
 return l
@@ -322,7 +318,6 @@
 'Set the location of tick in data coords with scalar loc'
 x = loc
 
-
 self.tick1line.set_xdata((x,))
 self.tick2line.set_xdata((x,))
 self.gridline.set_xdata((x, ))
@@ -334,6 +329,13 @@
 'return the Interval instance for this axis view limits'
 return self.axes.viewLim.intervalx
 
+ def set_view_interval(self, vmin, vmax, ignore = False):
+ if ignore:
+ self.axes.viewLim.intervalx = vmin, vmax
+ else:
+ Vmin, Vmax = self.get_view_interval()
+ self.axes.viewLim.intervalx = min(vmin, Vmin), max(vmax, Vmax)
+ 
 def get_minpos(self):
 return self.axes.dataLim.minposx
 
@@ -363,12 +365,7 @@
 dashdirection=0,
 xaxis=False,
 )
- trans = blended_transform_factory(
-	 self.axes.transAxes, self.axes.transData)
- # offset the text leftward with a post transformation
-	trans = trans + Affine2D().translate(-1 * self._padPixels, 0)
-
- t.set_transform( trans )
+ t.set_transform(self.axes.get_yaxis_text1_transform(self._padPixels))
 #t.set_transform( self.axes.transData )
 self._set_artist_props(t)
 return t
@@ -386,11 +383,7 @@
 xaxis=False,
 horizontalalignment='left',
 )
- trans = blended_transform_factory(
-	 self.axes.transAxes, self.axes.transData)
- # offset the text rightward with a post transformation
-	trans = trans + Affine2D().translate(self._padPixels, 0)
- t.set_transform( trans )
+ t.set_transform(self.axes.get_yaxis_text2_transform(self._padPixels))
 self._set_artist_props(t)
 return t
 
@@ -404,9 +397,7 @@
 linestyle = 'None',
 markersize=self._size,
 )
- l.set_transform(
-	 blended_transform_factory(
-		self.axes.transAxes, self.axes.transData))
+ l.set_transform(self.axes.get_yaxis_transform())
 self._set_artist_props(l)
 return l
 
@@ -420,9 +411,7 @@
 markersize=self._size,
 )
 
- l.set_transform(
-	 blended_transform_factory(
-		self.axes.transAxes, self.axes.transData))
+ l.set_transform(self.axes.get_yaxis_transform())
 self._set_artist_props(l)
 return l
 
@@ -436,10 +425,7 @@
 antialiased=False,
 )
 
- l.set_transform( blended_transform_factory(
-		self.axes.transAxes, self.axes.transData) )
- l.set_clip_box(self.axes.bbox)
-
+ l.set_transform(self.axes.get_yaxis_transform())
 self._set_artist_props(l)
 return l
 
@@ -461,6 +447,13 @@
 'return the Interval instance for this axis view limits'
 return self.axes.viewLim.intervaly
 
+ def set_view_interval(self, vmin, vmax):
+ if ignore:
+ self.axes.viewLim.intervaly = vmin, vmax
+ else:
+ Vmin, Vmax = self.get_view_interval()
+ self.axes.viewLim.intervaly = min(vmin, Vmin), max(vmax, Vmax)
+ 
 def get_minpos(self):
 return self.axes.dataLim.minposy
 
@@ -530,8 +523,8 @@
 
 def get_children(self):
 children = [self.label]
- majorticks = self.get_major_ticks()
- minorticks = self.get_minor_ticks() 
+ majorticks = self.get_major_ticks(len(self.major.locator()))
+ minorticks = self.get_minor_ticks(len(self.minor.locator())) 
 
 children.extend(majorticks)
 children.extend(minorticks)
@@ -565,11 +558,20 @@
 self.units = None
 self.set_units(None)
 
-
+ def set_clip_path(self, clippath, transform=None):
+ Artist.set_clip_path(self, clippath, transform)
+ majorticks = self.get_major_ticks(len(self.major.locator()))
+ minorticks = self.get_minor_ticks(len(self.minor.locator())) 
+ for child in self.majorTicks + self.minorTicks:
+ child.set_clip_path(clippath, transform)
+ 
 def get_view_interval(self):
 'return the Interval instance for this axis view limits'
 raise NotImplementedError('Derived must override')
 
+ def set_view_interval(self, vmin, vmax, ignore=False):
+ raise NotImplementedError('Derived must override')
+ 
 def get_data_interval(self):
 'return the Interval instance for this axis data limits'
 raise NotImplementedError('Derived must override')
@@ -585,8 +587,8 @@
 ticklabelBoxes = []
 ticklabelBoxes2 = []
 
- majorTicks = self.get_major_ticks()
 majorLocs = self.major.locator()
+ majorTicks = self.get_major_ticks(len(majorLocs))
 self.major.formatter.set_locs(majorLocs)
 majorLabels = [self.major.formatter(val, i) for i, val in enumerate(majorLocs)]
 
@@ -609,8 +611,8 @@
 extent = tick.label2.get_window_extent(renderer)
 ticklabelBoxes2.append(extent)
 
- minorTicks = self.get_minor_ticks()
 minorLocs = self.minor.locator()
+ minorTicks = self.get_minor_ticks(len(minorLocs))
 self.minor.formatter.set_locs(minorLocs)
 minorLabels = [self.minor.formatter(val, i) for i, val in enumerate(minorLocs)]
 
@@ -727,11 +729,9 @@
 'Get the formatter of the minor ticker'
 return self.minor.formatter
 
- def get_major_ticks(self):
+ def get_major_ticks(self, numticks):
 'get the tick instances; grow as necessary'
 
- numticks = len(self.major.locator())
-
 if len(self.majorTicks)<numticks:
 # update the new tick label properties from the old
 protoTick = self.majorTicks[0]
@@ -746,9 +746,8 @@
 return ticks
 
 
- def get_minor_ticks(self):
+ def get_minor_ticks(self, numticks):
 'get the minor tick instances; grow as necessary'
- numticks = len(self.minor.locator())
 if len(self.minorTicks)<numticks:
 protoTick = self.minorTicks[0]
 for i in range(numticks-len(self.minorTicks)):
@@ -949,8 +948,9 @@
 ### XXX if the user changes units, the information will be lost here
 ticks = self.convert_units(ticks)
 self.set_major_locator( FixedLocator(ticks) )
- self.get_view_interval().update(ticks,0)
- return self.get_major_ticks()
+ if len(ticks):
+ self.set_view_interval(min(ticks), max(ticks))
+ return self.get_major_ticks(len(ticks))
 
 def _update_label_position(self, bboxes, bboxes2):
 """
@@ -1153,6 +1153,13 @@
 'return the Interval instance for this axis view limits'
 return self.axes.viewLim.intervalx
 
+ def set_view_interval(self, vmin, vmax, ignore=False):
+ if ignore:
+ self.axes.viewLim.intervalx = vmin, vmax
+ else:
+ Vmin, Vmax = self.get_view_interval()
+ self.axes.viewLim.intervalx = min(vmin, Vmin), max(vmax, Vmax)
+ 
 def get_minpos(self):
 return self.axes.dataLim.minposx
 
@@ -1357,6 +1364,13 @@
 'return the Interval instance for this axis view limits'
 return self.axes.viewLim.intervaly
 
+ def set_view_interval(self, vmin, vmax, ignore=False):
+ if ignore:
+ self.axes.viewLim.intervaly = vmin, vmax
+ else:
+ Vmin, Vmax = self.get_view_interval()
+ self.axes.viewLim.intervaly = min(vmin, Vmin), max(vmax, Vmax)
+ 
 def get_minpos(self):
 return self.axes.dataLim.minposy
 
Modified: branches/transforms/lib/matplotlib/backend_bases.py
===================================================================
--- branches/transforms/lib/matplotlib/backend_bases.py	2007年10月02日 08:30:29 UTC (rev 3907)
+++ branches/transforms/lib/matplotlib/backend_bases.py	2007年10月03日 12:50:04 UTC (rev 3908)
@@ -537,7 +537,9 @@
 """
 Return the clip path
 """
- return self._clippath
+ if self._clippath is not None:
+ return self._clippath.get_transformed_path_and_affine()
+ return None, None
 
 def get_dashes(self):
 """
@@ -608,7 +610,7 @@
 
 def set_clip_path(self, path):
 """
- Set the clip path
+ Set the clip path and transformation
 """
 self._clippath = path
 
@@ -758,7 +760,7 @@
 return
 
 # Find all axes containing the mouse
- axes_list = [a for a in self.canvas.figure.get_axes() if a.in_axes(x, y)]
+ axes_list = [a for a in self.canvas.figure.get_axes() if a.in_axes(self)]
 
 if len(axes_list) == 0: # None found
 self.inaxes = None
@@ -1333,7 +1335,7 @@
 if event.key!='a':
 n=int(event.key)-1
 for i, a in enumerate(self.canvas.figure.get_axes()):
- if event.x is not None and event.y is not None and a.in_axes(event.x, event.y):
+ if event.x is not None and event.y is not None and a.in_axes(event):
 if event.key=='a':
 a.set_navigate(True)
 else:
@@ -1557,7 +1559,7 @@
 
 self._xypress=[]
 for i, a in enumerate(self.canvas.figure.get_axes()):
- if x is not None and y is not None and a.in_axes(x, y) and a.get_navigate():
+ if x is not None and y is not None and a.in_axes(event) and a.get_navigate():
 self._xypress.append((x, y, a, i, a.viewLim.frozen(), a.transData.frozen()))
 self.canvas.mpl_disconnect(self._idDrag)
 self._idDrag=self.canvas.mpl_connect('motion_notify_event', self.drag_pan)
@@ -1581,7 +1583,7 @@
 
 self._xypress=[]
 for i, a in enumerate(self.canvas.figure.get_axes()):
- if x is not None and y is not None and a.in_axes(x, y) and a.get_navigate():
+ if x is not None and y is not None and a.in_axes(event) and a.get_navigate():
 self._xypress.append(( x, y, a, i, a.viewLim.frozen(), a.transData.frozen()))
 
 self.press(event)
@@ -1621,33 +1623,12 @@
 def drag_pan(self, event):
 'the drag callback in pan/zoom mode'
 
- def format_deltas(event,dx,dy):
- if event.key=='control':
- if(abs(dx)>abs(dy)):
- dy = dx
- else:
- dx = dy
- elif event.key=='x':
- dy = 0
- elif event.key=='y':
- dx = 0
- elif event.key=='shift':
- if 2*abs(dx) < abs(dy):
- dx=0
- elif 2*abs(dy) < abs(dx):
- dy=0
- elif(abs(dx)>abs(dy)):
- dy=dy/abs(dy)*abs(dx)
- else:
- dx=dx/abs(dx)*abs(dy)
- return (dx,dy)
-
 for lastx, lasty, a, ind, old_lim, old_trans in self._xypress:
 #safer to use the recorded button at the press than current button:
 #multiple button can get pressed during motion...
 dx, dy = event.x - lastx, event.y - lasty
- dx, dy = format_deltas(event, dx, dy)
- a.drag_pan(self._button_pressed, lastx + dx, lasty + dy, lastx, lasty, old_lim, old_trans)
+ a.drag_pan(self._button_pressed, event.key, lastx, lasty, dx, dy,
+ old_lim, old_trans)
 self.dynamic_update()
 
 def release_zoom(self, event):
@@ -1664,7 +1645,7 @@
 self.draw()
 return
 
- xmin, ymin, xmax, ymax = lim
+ xmin, ymin, xmax, ymax = lim.lbrt
 
 # zoom to rect
 	 inverse = a.transData.inverted()
Modified: branches/transforms/lib/matplotlib/cbook.py
===================================================================
--- branches/transforms/lib/matplotlib/cbook.py	2007年10月02日 08:30:29 UTC (rev 3907)
+++ branches/transforms/lib/matplotlib/cbook.py	2007年10月03日 12:50:04 UTC (rev 3908)
@@ -1033,7 +1033,27 @@
 	itself.
 	"""
 	return self._mapping.get(a, [a])
-		
+
+ 
+def simple_linear_interpolation(a, steps):
+ steps = npy.floor(steps)
+ new_length = ((len(a) - 1) * steps) + 1
+ new_shape = list(a.shape)
+ new_shape[0] = new_length
+ result = npy.zeros(new_shape, a.dtype)
+
+ result[0] = a[0]
+ a0 = a[0:-1]
+ a1 = a[1: ]
+ delta = ((a1 - a0) / steps)
+
+ # MGDTODO: Could use linspace here?
+ for i in range(1, int(steps)):
+ result[i::steps] = delta * i + a0
+ result[steps::steps] = a1
+ 
+ return result
+
 if __name__=='__main__':
 assert( allequal([1,1,1]) )
 assert(not allequal([1,1,0]) )
Modified: branches/transforms/lib/matplotlib/figure.py
===================================================================
--- branches/transforms/lib/matplotlib/figure.py	2007年10月02日 08:30:29 UTC (rev 3907)
+++ branches/transforms/lib/matplotlib/figure.py	2007年10月03日 12:50:04 UTC (rev 3908)
@@ -7,7 +7,7 @@
 
 import artist
 from artist import Artist
-from axes import Axes, Subplot, PolarSubplot, PolarAxes
+from axes import Axes, SubplotBase, subplot_class_factory
 from cbook import flatten, allequal, Stack, iterable, dedent
 import _image
 import colorbar as cbar
@@ -22,6 +22,8 @@
 from transforms import Affine2D, Bbox, BboxTransform, TransformedBbox
 from cm import ScalarMappable
 from contour import ContourSet
+from projections import projection_factory, get_projection_names, \
+ get_projection_class
 import warnings
 
 class SubplotParams:
@@ -449,12 +451,17 @@
 """
 Add an a axes with axes rect [left, bottom, width, height] where all
 quantities are in fractions of figure width and height. kwargs are
- legal Axes kwargs plus "polar" which sets whether to create a polar axes
-
+ legal Axes kwargs plus "projection" which sets the projection type
+ of the axes. (For backward compatibility, polar=True may also be
+ provided, which is equivalent to projection='polar').
+ Valid values for "projection" are: %s. Some of these projections
+ support additional kwargs, which may be provided to add_axes.
+ 
 rect = l,b,w,h
 add_axes(rect)
 add_axes(rect, frameon=False, axisbg='g')
 add_axes(rect, polar=True)
+ add_axes(rect, projection='polar')
 add_axes(ax) # add an Axes instance
 
 
@@ -470,10 +477,10 @@
 add_axes(rect, label='axes2')
 
 The Axes instance will be returned
-
+ 
 The following kwargs are supported:
- %(Axes)s
- """
+ %s
+ """ % (", ".join(get_projection_names()), '%(Axes)s')
 
 key = self._make_key(*args, **kwargs)
 
@@ -489,13 +496,17 @@
 else:
 rect = args[0]
 ispolar = kwargs.pop('polar', False)
-
+ projection = kwargs.pop('projection', None)
 if ispolar:
- a = PolarAxes(self, rect, **kwargs)
- else:
- a = Axes(self, rect, **kwargs)
+ if projection is not None and projection != 'polar':
+ raise ValueError(
+ "polar=True, yet projection='%s'. " +
+ "Only one of these arguments should be supplied." %
+ projection)
+ projection = 'polar'
+ 
+ a = projection_factory(projection, self, rect, **kwargs)
 
-
 self.axes.append(a)
 self._axstack.push(a)
 self.sca(a)
@@ -513,15 +524,21 @@
 add_subplot(111, polar=True) # add a polar subplot
 add_subplot(sub) # add Subplot instance sub
 
- kwargs are legal Axes kwargs plus"polar" which sets whether to create a
- polar axes. The Axes instance will be returned.
+ kwargs are legal Axes kwargs plus "projection", which chooses
+ a projection type for the axes. (For backward compatibility,
+ polar=True may also be provided, which is equivalent to
+ projection='polar'). Valid values for "projection" are: %s.
+ Some of these projections support additional kwargs, which may
+ be provided to add_axes.
 
+ The Axes instance will be returned.
+ 
 If the figure already has a subplot with key *args, *kwargs then it will
 simply make that subplot current and return it
 
 The following kwargs are supported:
- %(Axes)s
- """
+ %s
+ """ % (", ".join(get_projection_names()), "%(Axes)s")
 
 key = self._make_key(*args, **kwargs)
 if self._seen.has_key(key):
@@ -532,16 +549,22 @@
 
 if not len(args): return
 
- if isinstance(args[0], Subplot) or isinstance(args[0], PolarSubplot):
+ if isinstance(args[0], SubplotBase):
 a = args[0]
 assert(a.get_figure() is self)
 else:
 ispolar = kwargs.pop('polar', False)
+ projection = kwargs.pop('projection', None)
 if ispolar:
- a = PolarSubplot(self, *args, **kwargs)
- else:
- a = Subplot(self, *args, **kwargs)
+ if projection is not None and projection != 'polar':
+ raise ValueError(
+ "polar=True, yet projection='%s'. " +
+ "Only one of these arguments should be supplied." %
+ projection)
+ projection = 'polar'
 
+ projection_class = get_projection_class(projection)
+ a = subplot_class_factory(projection_class)(self, *args, **kwargs)
 
 self.axes.append(a)
 self._axstack.push(a)
Modified: branches/transforms/lib/matplotlib/patches.py
===================================================================
--- branches/transforms/lib/matplotlib/patches.py	2007年10月02日 08:30:29 UTC (rev 3907)
+++ branches/transforms/lib/matplotlib/patches.py	2007年10月03日 12:50:04 UTC (rev 3908)
@@ -12,6 +12,8 @@
 import matplotlib.mlab as mlab
 import matplotlib.artist as artist
 from matplotlib.path import Path
+# MGDTODO: Maybe this belongs elsewhere
+from matplotlib.backends._backend_agg import point_in_path
 
 # these are not available for the object inspector until after the
 # class is build so we define an initial set here for the init
@@ -72,6 +74,7 @@
 self._linewidth = linewidth
 self._antialiased = antialiased
 self._hatch = hatch
+ self._combined_transform = transforms.IdentityTransform()
 self.fill = fill
 	
 if len(kwargs): artist.setp(self, **kwargs)
@@ -84,19 +87,15 @@
 
 Returns T/F, {}
 """
-	# MGDTODO: This will probably need to be implemented in C++
-
+	# This is a general version of contains should work on any
+ # patch with a path. However, patches that have a faster
+ # algebraic solution to hit-testing should override this
+ # method.
 	if callable(self._contains): return self._contains(self,mouseevent)
 
- try:
- # TODO: make this consistent with patch collection algorithm
- x, y = self.get_transform().inverse_xy_tup((mouseevent.x, mouseevent.y))
- xyverts = self.get_verts()
- inside = nxutils.pnpoly(x, y, xyverts)
- #print str(self),"%g,%g is in"%(x,y),xyverts,inside
- return inside,{}
- except ValueError:
- return False,{}
+ inside = point_in_path(mouseevent.x, mouseevent.y, self.get_path(),
+ self.get_transform().frozen())
+ return inside, {}
 
 def update_from(self, other):
 artist.Artist.update_from(self, other)
@@ -109,6 +108,17 @@
 self.set_figure(other.get_figure())
 self.set_alpha(other.get_alpha())
 
+ def get_transform(self):
+ return self._combined_transform
+
+ def set_transform(self, t):
+ artist.Artist.set_transform(self, t)
+ self._combined_transform = self.get_patch_transform() + \
+ artist.Artist.get_transform(self)
+
+ def get_patch_transform(self):
+ return transforms.IdentityTransform()
+ 
 def get_antialiased(self):
 return self._antialiased
 
@@ -207,12 +217,12 @@
 
 if not self.fill or self._facecolor is None: rgbFace = None
 else: rgbFace = colors.colorConverter.to_rgb(self._facecolor)
-
+ 
 if self._hatch:
 gc.set_hatch(self._hatch )
 
 path = self.get_path()
- transform = self.get_patch_transform() + self.get_transform()
+ transform = self.get_transform()
 
 renderer.draw_path(gc, path, transform, rgbFace)
 
@@ -226,12 +236,10 @@
 
 
 def get_window_extent(self, renderer=None):
- verts = self.get_verts()
- tverts = self.get_transform().seq_xy_tups(verts)
- return transforms.bound_vertices(tverts)
+ trans_path = self.get_path().transformed(self.get_path_transform())
+ return Bbox.unit().update_from_data(trans_path.vertices)
 
 
-
 def set_lw(self, val):
 'alias for set_linewidth'
 self.set_linewidth(val)
@@ -350,6 +358,11 @@
 
 def get_patch_transform(self):
 	return self._rect_transform
+
+ def contains(self, mouseevent):
+ x, y = self.get_transform().inverted().transform_point(
+ (mouseevent.x, mouseevent.y))
+ return (x >= 0.0 and x <= 1.0 and y >= 0.0 and y <= 1.0), {}
 
 def get_x(self):
 "Return the left coord of the rectangle"
@@ -445,8 +458,8 @@
 def get_path(self):
 	return self._path
 
- def get_transform(self):
-	return self._poly_transform + self._transform
+ def get_patch_transform(self):
+	return self._poly_transform
 	
 class Polygon(Patch):
 """
@@ -467,39 +480,35 @@
 	self._path = Path(xy, closed=True)
 __init__.__doc__ = cbook.dedent(__init__.__doc__) % artist.kwdocd
 
- def get_verts(self):
+ def get_path(self):
 	return self._path
-
- # MGDTODO: Convert units
- xs = self.convert_xunits(xs)
- ys = self.convert_yunits(ys)
-
-class Wedge(Polygon):
+ 
+class Wedge(Patch):
 def __str__(self):
 return "Wedge(%g,%g)"%self.xy[0]
- def __init__(self, center, r, theta1, theta2,
- dtheta=0.1, **kwargs):
+ def __init__(self, center, r, theta1, theta2, **kwargs):
 """
 Draw a wedge centered at x,y tuple center with radius r that
 sweeps theta1 to theta2 (angles)
 
- dtheta is the resolution in degrees
-
 Valid kwargs are:
 %(Patch)s
 
 """
-	# MGDTODO: Implement me
- xc, yc = center
- rads = (math.pi/180.)*npy.arange(theta1, theta2+0.1*dtheta, dtheta)
- xs = r*npy.cos(rads)+xc
- ys = r*npy.sin(rads)+yc
- ...
 
[truncated message content]
From: <md...@us...> - 2007年10月03日 12:51:20
Revision: 3909
 http://matplotlib.svn.sourceforge.net/matplotlib/?rev=3909&view=rev
Author: mdboom
Date: 2007年10月03日 05:51:16 -0700 (2007年10月03日)
Log Message:
-----------
Merged revisions 3906-3908 via svnmerge from 
http://matplotlib.svn.sf.net/svnroot/matplotlib/trunk/matplotlib
........
 r3907 | efiring | 2007年10月02日 04:30:29 -0400 (2007年10月02日) | 2 lines
 
 matplotlib.use() raises an exception if called too late
........
Modified Paths:
--------------
 branches/transforms/CHANGELOG
 branches/transforms/lib/matplotlib/__init__.py
Property Changed:
----------------
 branches/transforms/
Property changes on: branches/transforms
___________________________________________________________________
Name: svnmerge-integrated
 - /trunk/matplotlib:1-3905
 + /trunk/matplotlib:1-3908
Modified: branches/transforms/CHANGELOG
===================================================================
--- branches/transforms/CHANGELOG	2007年10月03日 12:50:04 UTC (rev 3908)
+++ branches/transforms/CHANGELOG	2007年10月03日 12:51:16 UTC (rev 3909)
@@ -1,3 +1,6 @@
+2007年10月01日 Made matplotlib.use() raise an exception if called after
+ backends has been imported.
+
 2007年09月30日 Modified update* methods of Bbox and Interval so they
 work with reversed axes. Prior to this, trying to
 set the ticks on a reversed axis failed with an
Modified: branches/transforms/lib/matplotlib/__init__.py
===================================================================
--- branches/transforms/lib/matplotlib/__init__.py	2007年10月03日 12:50:04 UTC (rev 3908)
+++ branches/transforms/lib/matplotlib/__init__.py	2007年10月03日 12:51:16 UTC (rev 3909)
@@ -716,6 +716,9 @@
 except:
 from config import rcParams, rcdefaults
 
+_use_error_msg = """ matplotlib.use() must be called *before* pylab
+or matplotlib.backends is imported for the first time."""
+
 def use(arg):
 """
 Set the matplotlib backend to one of the known backends.
@@ -732,6 +735,8 @@
 for the first time; or, if you are not using pylab, it must
 be called before importing matplotlib.backends.
 """
+ if 'matplotlib.backends' in sys.modules:
+ raise RuntimeError(_use_error_msg)
 be_parts = arg.split('.')
 name = validate_backend(be_parts[0])
 rcParams['backend'] = name
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
From: <md...@us...> - 2007年10月04日 17:21:31
Revision: 3912
 http://matplotlib.svn.sourceforge.net/matplotlib/?rev=3912&view=rev
Author: mdboom
Date: 2007年10月04日 10:21:26 -0700 (2007年10月04日)
Log Message:
-----------
Lots of new docstrings. Reasonably good state for polar plots.
r-axis labels can be dragged on polar plots. r-scale can be zoomed on
polar plot. Lots of other minor changes too numerous to mention.
Modified Paths:
--------------
 branches/transforms/lib/matplotlib/axes.py
 branches/transforms/lib/matplotlib/axis.py
 branches/transforms/lib/matplotlib/backend_bases.py
 branches/transforms/lib/matplotlib/backends/backend_agg.py
 branches/transforms/lib/matplotlib/legend.py
 branches/transforms/lib/matplotlib/lines.py
 branches/transforms/lib/matplotlib/patches.py
 branches/transforms/lib/matplotlib/path.py
 branches/transforms/lib/matplotlib/projections/polar.py
 branches/transforms/lib/matplotlib/pyplot.py
 branches/transforms/lib/matplotlib/ticker.py
 branches/transforms/lib/matplotlib/transforms.py
 branches/transforms/src/_backend_agg.cpp
 branches/transforms/src/_backend_agg.h
Modified: branches/transforms/lib/matplotlib/axes.py
===================================================================
--- branches/transforms/lib/matplotlib/axes.py	2007年10月03日 23:05:30 UTC (rev 3911)
+++ branches/transforms/lib/matplotlib/axes.py	2007年10月04日 17:21:26 UTC (rev 3912)
@@ -478,13 +478,12 @@
 """ % {'scale': ' | '.join([repr(x) for x in mscale.get_scale_names()])}
 martist.Artist.__init__(self)
 self._position = mtransforms.Bbox.from_lbwh(*rect)
- self._originalPosition = copy.deepcopy(self._position)
+ self._originalPosition = self._position.frozen()
 self.set_axes(self)
 self.set_aspect('auto')
 self.set_adjustable('box')
 self.set_anchor('C')
 
- # MGDTODO: Check that the axes being shared are scalable
 self._sharex = sharex
 self._sharey = sharey
 	if sharex is not None:
@@ -540,69 +539,6 @@
 self.yaxis = maxis.YAxis(self)
 self._update_transScale()
 
- def sharex_foreign(self, axforeign):
- """
- You can share your x-axis view limits with another Axes in the
- same Figure by using the sharex and sharey property of the
- Axes. But this doesn't work for Axes in a different figure.
- This function sets of the callbacks so that when the xaxis of
- this Axes or the Axes in a foreign figure are changed, both
- will be synchronized.
-
- The connection ids for the self.callbacks and
- axforeign.callbacks cbook.CallbackRegistry instances are
- returned in case you want to disconnect the coupling
- """
-
- def follow_foreign_xlim(ax):
- xmin, xmax = axforeign.get_xlim()
- # do not emit here or we'll get a ping png effect
- self.set_xlim(xmin, xmax, emit=False)
- self.figure.canvas.draw_idle()
-
- def follow_self_xlim(ax):
- xmin, xmax = self.get_xlim()
- # do not emit here or we'll get a ping png effect
- axforeign.set_xlim(xmin, xmax, emit=False)
- axforeign.figure.canvas.draw_idle()
-
-
- cidForeign = axforeign.callbacks.connect('xlim_changed', follow_foreign_xlim)
- cidSelf = self.callbacks.connect('xlim_changed', follow_self_xlim)
- return cidSelf, cidForeign
-
-
- def sharey_foreign(self, axforeign):
- """
- You can share your y-axis view limits with another Axes in the
- same Figure by using the sharey and sharey property of the
- Axes. But this doesn't work for Axes in a different figure.
- This function sets of the callbacks so that when the yaxis of
- this Axes or the Axes in a foreign figure are changed, both
- will be synchronized.
-
- The connection ids for the self.callbacks and
- axforeign.callbacks cbook.CallbackRegistry instances are
- returned in case you want to disconnect the coupling
- """
-
- def follow_foreign_ylim(ax):
- ymin, ymax = axforeign.get_ylim()
- # do not emit here or we'll get a ping pong effect
- self.set_ylim(ymin, ymax, emit=False)
- self.figure.canvas.draw_idle()
-
- def follow_self_ylim(ax):
- ymin, ymax = self.get_ylim()
- # do not emit here or we'll get a ping pong effect
- axforeign.set_ylim(ymin, ymax, emit=False)
- axforeign.figure.canvas.draw_idle()
-
-
- cidForeign = axforeign.callbacks.connect('ylim_changed', follow_foreign_ylim)
- cidSelf = self.callbacks.connect('ylim_changed', follow_self_ylim)
- return cidSelf, cidForeign
-
 def set_figure(self, fig):
 """
 Set the Axes figure
@@ -629,10 +565,6 @@
 # It is assumed that this part will have non-linear components
 self.transScale = mtransforms.TransformWrapper(mtransforms.IdentityTransform())
 
- self._set_transData()
-
- # MGDTODO: Rename this method
- def _set_transData(self):
 # A (possibly non-linear) projection on the (already scaled) data
 self.transProjection = mtransforms.IdentityTransform()
 
@@ -648,34 +580,38 @@
 self._yaxis_transform = mtransforms.blended_transform_factory(
 self.axes.transAxes, self.axes.transData)
 
+ self.transData.write_graphviz(open("trans.dot", "w"))
+
 def get_xaxis_transform(self):
 return self._xaxis_transform
 
 def get_xaxis_text1_transform(self, pad_pixels):
 return (self._xaxis_transform +
- mtransforms.Affine2D().translate(0, -1 * pad_pixels))
+ mtransforms.Affine2D().translate(0, -1 * pad_pixels),
+ "top", "center")
 
 def get_xaxis_text2_transform(self, pad_pixels):
 return (self._xaxis_transform +
- mtransforms.Affine2D().translate(0, pad_pixels))
+ mtransforms.Affine2D().translate(0, pad_pixels),
+ "top", "center")
 
 def get_yaxis_transform(self):
 return self._yaxis_transform
 
 def get_yaxis_text1_transform(self, pad_pixels):
 return (self._yaxis_transform +
- mtransforms.Affine2D().translate(-1 * pad_pixels, 0))
+ mtransforms.Affine2D().translate(-1 * pad_pixels, 0),
+ "center", "right")
 
 def get_yaxis_text2_transform(self, pad_pixels):
 return (self._yaxis_transform +
- mtransforms.Affine2D().translate(pad_pixels, 0))
+ mtransforms.Affine2D().translate(pad_pixels, 0),
+ "center", "right")
 
 def _update_transScale(self):
 self.transScale.set(
 mtransforms.blended_transform_factory(
 self.xaxis.get_transform(), self.yaxis.get_transform()))
-
- self.transData.make_graphviz(open("trans.dot", "w"))
 
 def get_position(self, original=False):
 'Return the axes rectangle left, bottom, width, height'
@@ -1164,7 +1100,8 @@
 # limits and set the bound to be the bounds of the xydata.
 # Otherwise, it will compute the bounds of it's current data
 # and the data in xydata
- xys = npy.asarray(xys)
+ if not ma.isMaskedArray(xys):
+ xys = npy.asarray(xys)
 self.update_datalim_numerix(xys[:, 0], xys[:, 1])
 
 def update_datalim_numerix(self, x, y):
@@ -1535,7 +1472,9 @@
 	 for other in self._shared_x_axes.get_siblings(self):
 		if other is not self:
 		 other.set_xlim(self.viewLim.intervalx, emit=False)
-	 
+
+ self.figure.canvas.draw_idle()
+ 
 return xmin, xmax
 
 def get_xscale(self):
@@ -1641,7 +1580,9 @@
 	 for other in self._shared_y_axes.get_siblings(self):
 		if other is not self:
 		 other.set_ylim(self.viewLim.ymin, self.viewLim.ymax, emit=False)
-	 
+
+ self.figure.canvas.draw_idle()
+ 
 return ymin, ymax
 
 def get_yscale(self):
@@ -1795,8 +1736,19 @@
 """
 self._navigate_mode = b
 
- def drag_pan(self, button, key, startx, starty, dx, dy,
- start_lim, start_trans):
+ def start_pan(self, x, y, button):
+ self._pan_start = cbook.Bunch(
+ lim = self.viewLim.frozen(),
+ trans = self.transData.frozen(),
+ trans_inverse = self.transData.inverted().frozen(),
+ x = x,
+ y = y
+ )
+
+ def end_pan(self):
+ del self._pan_start
+ 
+ def drag_pan(self, button, key, x, y):
 def format_deltas(key, dx, dy):
 if key=='control':
 if(abs(dx)>abs(dy)):
@@ -1818,22 +1770,24 @@
 dx=dx/abs(dx)*abs(dy)
 return (dx,dy)
 
+ p = self._pan_start
+ dx = x - p.x
+ dy = y - p.y
 if button == 1:
- inverse = start_trans.inverted()
 dx, dy = format_deltas(key, dx, dy)
- result = self.bbox.frozen().translated(-dx, -dy).transformed(inverse)
+ result = self.bbox.frozen().translated(-dx, -dy) \
+ .transformed(p.trans_inverse)
 elif button == 3:
 try:
 # MGDTODO: This is broken with log scales
- inverse = start_trans.inverted()
 dx, dy = format_deltas(key, dx, dy)
 dx = -dx / float(self.bbox.width)
 dy = -dy / float(self.bbox.height)
- xmin, ymin, xmax, ymax = start_lim.lbrt
+ xmin, ymin, xmax, ymax = p.lim.lbrt
 
 alpha = npy.power(10.0, (dx, dy))
- start = inverse.transform_point((startx, starty))
- lim_points = start_lim.get_points()
+ start = p.trans_inverse.transform_point((p.x, p.y))
+ lim_points = p.lim.get_points()
 result = start + alpha * (lim_points - start)
 result = mtransforms.Bbox(result)
 except OverflowError:
@@ -5214,485 +5168,16 @@
 label.set_visible(firstcol)
 
 def subplot_class_factory(axes_class=None):
- # MGDTODO: This is a little bit strange to make a new class on the
- # fly like this, but it keeps things relatively similar to how they
- # were before
+ # This makes a new class that inherits from SubclassBase and the
+ # given axes_class (which is assumed to be a subclass of Axes).
+ 
+ # This is perhaps a little bit roundabout to make a new class on
+ # the fly like this, but it means that a new Subplot class does
+ # not have to be created for every type of Axes.
 new_class = new.classobj("%sSubplot" % (axes_class.__name__),
 (SubplotBase, axes_class),
 {'_axes_class': axes_class})
 return new_class
-
-
-class PolarAxes(Axes):
- """
- Make a PolarAxes. The rectangular bounding box of the axes is given by
-
-
- PolarAxes(position=[left, bottom, width, height])
-
- where all the arguments are fractions in [0,1] which specify the
- fraction of the total figure window.
-
- axisbg is the color of the axis background
-
- Attributes:
- thetagridlines : a list of Line2D for the theta grids
- rgridlines : a list of Line2D for the radial grids
- thetagridlabels : a list of Text for the theta grid labels
- rgridlabels : a list of Text for the theta grid labels
-
- """
-
- RESOLUTION = 100
-
- def __init__(self, *args, **kwarg):
- """
- See Axes base class for args and kwargs documentation
- """
- Axes.__init__(self, *args, **kwarg)
- self.set_aspect('equal', adjustable='box', anchor='C')
- self.cla()
- def _init_axis(self):
- "nuthin to do"
- self.xaxis = None
- self.yaxis = None
-
-
- def _set_lim_and_transforms(self):
- """
- set the dataLim and viewLim BBox attributes and the
- transData and transAxes Transformation attributes
- """
-
- # the lim are theta, r
-
-	# MGDTODO
-# Bbox = mtrans.Bbox
-# Value = mtrans.Value
-# Point = mtrans.Point
-# self.dataLim = Bbox( Point( Value(5/4.*math.pi), Value(math.sqrt(2))),
-# Point( Value(1/4.*math.pi), Value(math.sqrt(2))))
-# self.viewLim = Bbox( Point( Value(5/4.*math.pi), Value(math.sqrt(2))),
-# Point( Value(1/4.*math.pi), Value(math.sqrt(2))))
-
-# self.transData = mtrans.NonseparableTransformation(
-# self.viewLim, self.bbox,
-# mtrans.FuncXY(mtrans.POLAR))
-# self.transAxes = mtrans.get_bbox_transform(
-# mtrans.unit_bbox(), self.bbox)
-	pass
-
- def contains(self,mouseevent):
- """Test whether the mouse event occured in the axes.
-
- Returns T/F, {}
- """
- if callable(self._contains): return self._contains(self,mouseevent)
-
- x,y = self.axes.transAxes.inverse_xy_tup((mouseevent.x,mouseevent.y))
- #print "Polar: x,y = ",x,y
- inside = (x-0.5)**2 + (y-0.5)**2 <= 0.25
- return inside,{}
-
- def cla(self):
- 'Clear the current axes'
-
- # init these w/ some arbitrary numbers - they'll be updated as
- # data is added to the axes
-
- self._get_lines = _process_plot_var_args(self)
- self._get_patches_for_fill = _process_plot_var_args(self, 'fill')
-
- self._gridOn = rcParams['polaraxes.grid']
- self.thetagridlabels = []
- self.thetagridlines = []
- self.rgridlabels = []
- self.rgridlines = []
-
- self.lines = []
- self.images = []
- self.patches = []
- self.artists = []
- self.collections = []
- self.texts = [] # text in axis coords
- self.legend_ = None
-
- self.grid(self._gridOn)
- props = font_manager.FontProperties(size=rcParams['axes.titlesize'])
- self.title = mtext.Text(
- x=0.5, y=1.05, text='',
- fontproperties=props,
- verticalalignment='bottom',
- horizontalalignment='center',
- )
- self.title.set_transform(self.transAxes)
-
- self._set_artist_props(self.title)
-
-
- self.thetas = npy.linspace(0, 2*math.pi, self.RESOLUTION)
-
- verts = zip(self.thetas, npy.ones(self.RESOLUTION))
- self.axesPatch = mpatches.Polygon(
- verts,
- facecolor=self._axisbg,
- edgecolor=rcParams['axes.edgecolor'],
- )
-
-
-
- self.axesPatch.set_figure(self.figure)
- self.axesPatch.set_transform(self.transData)
- self.axesPatch.set_linewidth(rcParams['axes.linewidth'])
- self.axison = True
-
- # we need to set a view and data interval from 0->rmax to make
- # the formatter and locator work correctly
-	# MGDTODO
- Value = mtrans.Value
- Interval = mtrans.Interval
- self.rintv = Interval(Value(0), Value(1))
- self.rintd = Interval(Value(0), Value(1))
-
- self.rformatter = mticker.ScalarFormatter()
- self.rformatter.set_view_interval(self.rintv)
- self.rformatter.set_data_interval(self.rintd)
-
- class RadialLocator(mticker.AutoLocator):
- 'enforce strictly positive radial ticks'
-
- def __call__(self):
- ticks = mticker.AutoLocator.__call__(self)
- return [t for t in ticks if t>0]
-
- self.rlocator = RadialLocator()
- self.rlocator.set_view_interval(self.rintv)
- self.rlocator.set_data_interval(self.rintd)
-
-
- angles = npy.arange(0, 360, 45)
- radii = npy.arange(0.2, 1.1, 0.2)
- self.set_thetagrids(angles)
- self.set_rgrids(radii)
-
- def get_children(self):
- 'return a list of child artists'
- children = []
- children.extend(self.rgridlines)
- children.extend(self.rgridlabels)
- children.extend(self.thetagridlines)
- children.extend(self.thetagridlabels)
- children.extend(self.lines)
- children.extend(self.patches)
- children.extend(self.texts)
- children.extend(self.artists)
- children.extend(self.images)
- if self.legend_ is not None:
- children.append(self.legend_)
- children.extend(self.collections)
- children.append(self.title)
- children.append(self.axesPatch)
- return children
-
-
- def set_rmax(self, rmax):
- self.rintv.set_bounds(0, rmax)
- self.regrid(rmax)
-
- def grid(self, b):
- 'Set the axes grids on or off; b is a boolean'
- self._gridOn = b
-
- def regrid(self, rmax):
- rmax = float(rmax)
- self.axesPatch.xy = zip(self.thetas, rmax*npy.ones(self.RESOLUTION))
-
- val = rmax*math.sqrt(2)
- self.viewLim.intervaly().set_bounds(val, val)
-
- ticks = self.rlocator()
- self.set_rgrids(ticks)
- self.rformatter.set_locs(ticks)
-
- for t in self.thetagridlabels:
- t.set_y(1.05*rmax)
-
- r = npy.linspace(0, rmax, self.RESOLUTION)
- for l in self.thetagridlines:
- l.set_ydata(r)
-
- def autoscale_view(self, scalex=True, scaley=True):
- 'set the view limits to include all the data in the axes'
- self.rintd.set_bounds(0, self.get_rmax())
- rmin, rmax = self.rlocator.autoscale()
- self.rintv.set_bounds(rmin, rmax)
- self.regrid(rmax)
-
- def set_rgrids(self, radii, labels=None, angle=22.5, rpad=0.05, **kwargs):
- """
- set the radial locations and labels of the r grids
-
- The labels will appear at radial distances radii at angle
-
- labels, if not None, is a len(radii) list of strings of the
- labels to use at each angle.
-
- if labels is None, the self.rformatter will be used
-
- rpad is a fraction of the max of radii which will pad each of
- the radial labels in the radial direction.
-
- Return value is a list of lines, labels where the lines are
- lines.Line2D instances and the labels are text.Text
- instances
-
- kwargs control the rgrid Text label properties:
- %(Text)s
-
- ACCEPTS: sequence of floats
- """
-
-
- radii = npy.asarray(radii)
- rmin = radii.min()
- if rmin<=0:
- raise ValueError('radial grids must be strictly positive')
-
- rpad = rpad * max(radii)
- cbook.popall(self.rgridlines)
-
- theta = npy.linspace(0., 2*math.pi, self.RESOLUTION)
- ls = rcParams['grid.linestyle']
- color = rcParams['grid.color']
- lw = rcParams['grid.linewidth']
-
- rmax = self.get_rmax()
- for r in radii:
- r = npy.ones(self.RESOLUTION)*r
- line = mlines.Line2D(theta, r, linestyle=ls, color=color, linewidth=lw,
- figure=self.figure)
- line.set_transform(self.transData)
- self.rgridlines.append(line)
-
- cbook.popall(self.rgridlabels)
-
-
- color = rcParams['xtick.color']
-
-
- props = font_manager.FontProperties(size=rcParams['xtick.labelsize'])
- if labels is None:
- labels = [self.rformatter(r,0) for r in radii]
- for r,l in zip(radii, labels):
- t = mtext.Text(angle/180.*math.pi, r+rpad, l,
- fontproperties=props, color=color,
- horizontalalignment='center', verticalalignment='center')
- t.set_transform(self.transData)
- t.update(kwargs)
- self._set_artist_props(t)
- t.set_clip_on(False)
- self.rgridlabels.append(t)
-
- return self.rgridlines, self.rgridlabels
- set_rgrids.__doc__ = cbook.dedent(set_rgrids.__doc__) % martist.kwdocd
-
- def set_thetagrids(self, angles, labels=None, fmt='%d', frac = 1.1,
- **kwargs):
- """
- set the angles at which to place the theta grids (these
- gridlines are equal along the theta dimension). angles is in
- degrees
-
- labels, if not None, is a len(angles) list of strings of the
- labels to use at each angle.
-
- if labels is None, the labels with be fmt%%angle
-
- frac is the fraction of the polar axes radius at which to
- place the label (1 is the edge).Eg 1.05 isd outside the axes
- and 0.95 is inside the axes
-
- Return value is a list of lines, labels where the lines are
- lines.Line2D instances and the labels are Text
- instances:
-
- kwargs are optional text properties for the labels
- %(Text)s
- ACCEPTS: sequence of floats
- """
- cbook.popall(self.thetagridlines)
- ox, oy = 0,0
- ls = rcParams['grid.linestyle']
- color = rcParams['grid.color']
- lw = rcParams['grid.linewidth']
-
- rmax = self.get_rmax()
- r = npy.linspace(0., rmax, self.RESOLUTION)
- for a in angles:
- theta = npy.ones(self.RESOLUTION)*a/180.*math.pi
- line = mlines.Line2D(
- theta, r, linestyle=ls, color=color, linewidth=lw,
- figure=self.figure)
- line.set_transform(self.transData)
- self.thetagridlines.append(line)
-
- cbook.popall(self.thetagridlabels)
-
- color = rcParams['xtick.color']
-
- props = font_manager.FontProperties(size=rcParams['xtick.labelsize'])
- r = frac*rmax
- if labels is None:
- labels = [fmt%a for a in angles]
- for a,l in zip(angles, labels):
- t = mtext.Text(a/180.*math.pi, r, l, fontproperties=props, color=color,
- horizontalalignment='center', verticalalignment='center')
- t.set_transform(self.transData)
- t.update(kwargs)
- self._set_artist_props(t)
- t.set_clip_on(False)
- self.thetagridlabels.append(t)
- return self.thetagridlines, self.thetagridlabels
- set_thetagrids.__doc__ = cbook.dedent(set_thetagrids.__doc__) % martist.kwdocd
-
- def get_rmax(self):
- 'get the maximum radius in the view limits dimension'
- vmin, vmax = self.dataLim.intervaly().get_bounds()
- return max(vmin, vmax)
-
- def draw(self, renderer):
- if not self.get_visible(): return
- renderer.open_group('polar_axes')
- self.apply_aspect(1)
- self.transData.freeze() # eval the lazy objects
- self.transAxes.freeze() # eval the lazy objects
-
- verts = self.axesPatch.get_verts()
- tverts = self.transData.seq_xy_tups(verts)
-
- #for i,v,t in zip(range(len(verts)), verts, tverts):
- # print i,v,t
-
-
-
- l,b,w,h = self.figure.bbox.get_bounds()
- clippath = agg.path_storage()
- for i, xy in enumerate(tverts):
- x,y = xy
- y = h-y
- if i==0: clippath.move_to(x, y)
- else: clippath.line_to(x, y)
- clippath.close_polygon()
-
- #self._update_axes()
- if self.axison:
- if self._frameon: self.axesPatch.draw(renderer)
-
- if self._gridOn:
- for l in self.rgridlines:
- l.set_clip_path(clippath)
- l.draw(renderer)
-
- for l in self.thetagridlines:
- l.set_clip_path(clippath)
- l.draw(renderer)
-
- for a in self.lines:# + self.patches:
- a.set_clip_path(clippath)
-
- artists = []
- artists.extend(self.lines)
- artists.extend(self.texts)
- artists.extend(self.collections)
- artists.extend(self.patches)
- artists.extend(self.artists)
-
- dsu = [ (a.zorder, a) for a in artists]
- dsu.sort()
-
- for zorder, a in dsu:
- a.draw(renderer)
-
-
- for t in self.thetagridlabels+self.rgridlabels:
- t.draw(renderer)
-
- if self.legend_ is not None:
- self.legend_.draw(renderer)
-
- self.title.draw(renderer)
-
-
-
- self.transData.thaw() # release the lazy objects
- self.transAxes.thaw() # release the lazy objects
- renderer.close_group('polar_axes')
-
-
- def format_coord(self, theta, r):
- 'return a format string formatting the coordinate'
- theta /= math.pi
- return 'theta=%1.2fpi, r=%1.3f'%(theta, r)
-
-
- def has_data(self):
- 'return true if any artists have been added to axes'
- return len(self.lines)+len(self.collections)
-
- def set_xlabel(self, xlabel, fontdict=None, **kwargs):
- 'xlabel not implemented'
- raise NotImplementedError('xlabel not defined for polar axes (yet)')
-
- def set_ylabel(self, ylabel, fontdict=None, **kwargs):
- 'ylabel not implemented'
- raise NotImplementedError('ylabel not defined for polar axes (yet)')
-
- def set_xlim(self, xmin=None, xmax=None, emit=True, **kwargs):
- 'xlim not implemented'
- raise NotImplementedError('xlim not meaningful for polar axes')
-
- def set_ylim(self, ymin=None, ymax=None, emit=True, **kwargs):
- 'ylim not implemented'
- raise NotImplementedError('ylim not meaningful for polar axes')
-
- def get_xscale(self):
- 'return the xaxis scale string'
- return 'polar'
-
- def get_yscale(self):
- 'return the yaxis scale string'
- return 'polar'
-
- def table(self, *args, **kwargs):
- """
- TABLE(*args, **kwargs)
- Not implemented for polar axes
- """
- raise NotImplementedError('table not implemented for polar axes')
-
-
-
-class PolarSubplot(SubplotBase, PolarAxes):
- """
- Create a polar subplot with
-
- PolarSubplot(numRows, numCols, plotNum)
-
- where plotNum=1 is the first plot number and increasing plotNums
- fill rows first. max(plotNum)==numRows*numCols
-
- You can leave out the commas if numRows<=numCols<=plotNum<10, as
- in
-
- Subplot(211) # 2 rows, 1 column, first (upper) plot
- """
- def __str__(self):
- return "PolarSubplot(%gx%g)"%(self.figW,self.figH)
- def __init__(self, fig, *args, **kwargs):
- SubplotBase.__init__(self, fig, *args)
- PolarAxes.__init__(
- self, fig,
- [self.figLeft, self.figBottom, self.figW, self.figH], **kwargs)
 
 martist.kwdocd['Axes'] = martist.kwdocd['Subplot'] = martist.kwdoc(Axes)
 
Modified: branches/transforms/lib/matplotlib/axis.py
===================================================================
--- branches/transforms/lib/matplotlib/axis.py	2007年10月03日 23:05:30 UTC (rev 3911)
+++ branches/transforms/lib/matplotlib/axis.py	2007年10月04日 17:21:26 UTC (rev 3912)
@@ -166,7 +166,7 @@
 def draw(self, renderer):
 if not self.get_visible(): return
 renderer.open_group(self.__name__)
- midPoint = interval_contains_open(self.get_view_interval(), self.get_loc() )
+ midPoint = interval_contains(self.get_view_interval(), self.get_loc())
 
 if midPoint:
 if self.gridOn:
@@ -176,8 +176,10 @@
 if self.tick2On:
 self.tick2line.draw(renderer)
 
- if self.label1On: self.label1.draw(renderer)
- if self.label2On: self.label2.draw(renderer)
+ if self.label1On:
+ self.label1.draw(renderer)
+ if self.label2On:
+ self.label2.draw(renderer)
 
 renderer.close_group(self.__name__)
 
@@ -237,17 +239,19 @@
 # get the affine as an a,b,c,d,tx,ty list
 # x in data coords, y in axes coords
 #t = Text(
+ trans, vert, horiz = self.axes.get_xaxis_text1_transform(self._padPixels)
+ 
 t = TextWithDash(
 x=loc, y=0,
 fontproperties=FontProperties(size=rcParams['xtick.labelsize']),
 color=rcParams['xtick.color'],
- verticalalignment='top',
- horizontalalignment='center',
+ verticalalignment=vert,
+ horizontalalignment=horiz,
 dashdirection=0,
 xaxis=True,
 )
 
- t.set_transform(self.axes.get_xaxis_text1_transform(self._padPixels))
+ t.set_transform(trans)
 self._set_artist_props(t)
 return t
 
@@ -257,17 +261,19 @@
 'Get the default Text 2 instance'
 # x in data coords, y in axes coords
 #t = Text(
+ trans, vert, horiz = self.axes.get_xaxis_text2_transform(self._padPixels)
+
 t = TextWithDash(
 x=loc, y=1,
 fontproperties=FontProperties(size=rcParams['xtick.labelsize']),
 color=rcParams['xtick.color'],
- verticalalignment='bottom',
+ verticalalignment=vert,
 dashdirection=1,
 xaxis=True,
- horizontalalignment='center',
+ horizontalalignment=horiz,
 )
 
- t.set_transform(self.axes.get_xaxis_text2_transform(self._padPixels))
+ t.set_transform(trans)
 self._set_artist_props(t)
 return t
 
@@ -277,7 +283,6 @@
 l = Line2D( xdata=(loc,), ydata=(0,),
 color='k',
 linestyle = 'None',
- antialiased=False,
 marker = self._xtickmarkers[0],
 markersize=self._size,
 )
@@ -291,7 +296,6 @@
 l = Line2D( xdata=(loc,), ydata=(1,),
 color='k',
 linestyle = 'None',
- antialiased=False,
 marker = self._xtickmarkers[1],
 markersize=self._size,
 )
@@ -307,7 +311,6 @@
 color=rcParams['grid.color'],
 linestyle=rcParams['grid.linestyle'],
 linewidth=rcParams['grid.linewidth'],
- antialiased=False,
 )
 l.set_transform(self.axes.get_xaxis_transform())
 self._set_artist_props(l)
@@ -356,16 +359,18 @@
 'Get the default Text instance'
 # x in axes coords, y in data coords
 #t = Text(
- t = TextWithDash(
+ trans, vert, horiz = self.axes.get_yaxis_text1_transform(self._padPixels)
+
+ t = TextWithDash(
 x=0, y=loc,
 fontproperties=FontProperties(size=rcParams['ytick.labelsize']),
 color=rcParams['ytick.color'],
- verticalalignment='center',
- horizontalalignment='right',
+ verticalalignment=vert,
+ horizontalalignment=horiz,
 dashdirection=0,
 xaxis=False,
 )
- t.set_transform(self.axes.get_yaxis_text1_transform(self._padPixels))
+ t.set_transform(trans)
 #t.set_transform( self.axes.transData )
 self._set_artist_props(t)
 return t
@@ -374,16 +379,18 @@
 'Get the default Text instance'
 # x in axes coords, y in data coords
 #t = Text(
+ trans, vert, horiz = self.axes.get_yaxis_text2_transform(self._padPixels)
+
 t = TextWithDash(
 x=1, y=loc,
 fontproperties=FontProperties(size=rcParams['ytick.labelsize']),
 color=rcParams['ytick.color'],
- verticalalignment='center',
+ verticalalignment=vert,
 dashdirection=1,
 xaxis=False,
- horizontalalignment='left',
+ horizontalalignment=horiz,
 )
- t.set_transform(self.axes.get_yaxis_text2_transform(self._padPixels))
+ t.set_transform(trans)
 self._set_artist_props(t)
 return t
 
@@ -392,7 +399,6 @@
 # x in axes coords, y in data coords
 
 l = Line2D( (0,), (loc,), color='k',
- antialiased=False,
 marker = self._ytickmarkers[0],
 linestyle = 'None',
 markersize=self._size,
@@ -405,7 +411,6 @@
 'Get the default line2D instance'
 # x in axes coords, y in data coords
 l = Line2D( (1,), (0,), color='k',
- antialiased=False,
 marker = self._ytickmarkers[1],
 linestyle = 'None',
 markersize=self._size,
@@ -422,7 +427,6 @@
 color=rcParams['grid.color'],
 linestyle=rcParams['grid.linestyle'],
 linewidth=rcParams['grid.linewidth'],
- antialiased=False,
 )
 
 l.set_transform(self.axes.get_yaxis_transform())
@@ -523,8 +527,8 @@
 
 def get_children(self):
 children = [self.label]
- majorticks = self.get_major_ticks(len(self.major.locator()))
- minorticks = self.get_minor_ticks(len(self.minor.locator())) 
+ majorticks = self.get_major_ticks()
+ minorticks = self.get_minor_ticks() 
 
 children.extend(majorticks)
 children.extend(minorticks)
@@ -560,8 +564,8 @@
 
 def set_clip_path(self, clippath, transform=None):
 Artist.set_clip_path(self, clippath, transform)
- majorticks = self.get_major_ticks(len(self.major.locator()))
- minorticks = self.get_minor_ticks(len(self.minor.locator())) 
+ majorticks = self.get_major_ticks()
+ minorticks = self.get_minor_ticks() 
 for child in self.majorTicks + self.minorTicks:
 child.set_clip_path(clippath, transform)
 
@@ -729,9 +733,11 @@
 'Get the formatter of the minor ticker'
 return self.minor.formatter
 
- def get_major_ticks(self, numticks):
+ def get_major_ticks(self, numticks=None):
 'get the tick instances; grow as necessary'
-
+ if numticks is None:
+ numticks = len(self.get_major_locator()())
+ 
 if len(self.majorTicks)<numticks:
 # update the new tick label properties from the old
 protoTick = self.majorTicks[0]
@@ -746,8 +752,11 @@
 return ticks
 
 
- def get_minor_ticks(self, numticks):
+ def get_minor_ticks(self, numticks=None):
 'get the minor tick instances; grow as necessary'
+ if numticks is None:
+ numticks = len(self.get_minor_locator()())
+
 if len(self.minorTicks)<numticks:
 protoTick = self.minorTicks[0]
 for i in range(numticks-len(self.minorTicks)):
Modified: branches/transforms/lib/matplotlib/backend_bases.py
===================================================================
--- branches/transforms/lib/matplotlib/backend_bases.py	2007年10月03日 23:05:30 UTC (rev 3911)
+++ branches/transforms/lib/matplotlib/backend_bases.py	2007年10月04日 17:21:26 UTC (rev 3912)
@@ -34,40 +34,22 @@
 
 def draw_path(self, gc, path, transform, rgbFace=None):
 	"""
-	Handles the caching of the native path associated with the
-	given path and calls the underlying backend's _draw_path to
-	actually do the drawing.
+ Draws a Path instance using the given affine transform.
 	"""
- # MGDTODO: Update docstring
 raise NotImplementedError
 
 def draw_markers(self, gc, marker_path, marker_trans, path, trans, rgbFace=None):
 """
- This method is currently underscore hidden because the
- draw_markers method is being used as a sentinel for newstyle
- backend drawing
+ Draws a marker at each of the vertices in path. This includes
+ all vertices, including control points on curves. To avoid
+ that behavior, those vertices should be removed before calling
+ this function.
 
- path - a matplotlib.agg.path_storage instance
-
- Draw the marker specified in path with graphics context gc at
- each of the locations in arrays x and y. trans is a
- matplotlib.transforms.Transformation instance used to
- transform x and y to display coords. It consists of an
- optional nonlinear component and an affine. You can access
- these two components as
-
- if transform.need_nonlinear():
- x,y = transform.nonlinear_only_numerix(x, y)
- # the a,b,c,d,tx,ty affine which transforms x and y
- vec6 = transform.as_vec6_val()
- ...backend dependent affine...
+ marker_trans is an affine transform applied to the marker.
+ trans is an affine transform applied to the path.
 """
- # MGDTODO: Update docstring
 raise NotImplementedError
 	
- def _draw_native_markers(self, gc, native_marker_path, marker_trans, path, trans, rgbFace=None):
- raise NotImplementedError
-
 def get_image_magnification(self):
 """
 Get the factor by which to magnify images passed to draw_image.
@@ -1560,7 +1542,8 @@
 self._xypress=[]
 for i, a in enumerate(self.canvas.figure.get_axes()):
 if x is not None and y is not None and a.in_axes(event) and a.get_navigate():
- self._xypress.append((x, y, a, i, a.viewLim.frozen(), a.transData.frozen()))
+ a.start_pan(x, y, event.button)
+ self._xypress.append((a, i))
 self.canvas.mpl_disconnect(self._idDrag)
 self._idDrag=self.canvas.mpl_connect('motion_notify_event', self.drag_pan)
 
@@ -1597,14 +1580,12 @@
 lims.append( (xmin, xmax, ymin, ymax) )
 # Store both the original and modified positions
 pos.append( (
-		 copy.copy(a.get_position(True)),
- copy.copy(a.get_position() )) )
+		 a.get_position(True).frozen(),
+ a.get_position().frozen() ) )
 self._views.push(lims)
 self._positions.push(pos)
 self.set_history_buttons()
 
-
-
 def release(self, event):
 'this will be called whenever mouse button is released'
 pass
@@ -1613,6 +1594,8 @@
 'the release mouse button callback in pan/zoom mode'
 self.canvas.mpl_disconnect(self._idDrag)
 self._idDrag=self.canvas.mpl_connect('motion_notify_event', self.mouse_move)
+ for a, ind in self._xypress:
+ a.end_pan()
 if not self._xypress: return
 self._xypress = None
 self._button_pressed=None
@@ -1623,12 +1606,10 @@
 def drag_pan(self, event):
 'the drag callback in pan/zoom mode'
 
- for lastx, lasty, a, ind, old_lim, old_trans in self._xypress:
+ for a, ind in self._xypress:
 #safer to use the recorded button at the press than current button:
 #multiple button can get pressed during motion...
- dx, dy = event.x - lastx, event.y - lasty
- a.drag_pan(self._button_pressed, event.key, lastx, lasty, dx, dy,
- old_lim, old_trans)
+ a.drag_pan(self._button_pressed, event.key, event.x, event.y)
 self.dynamic_update()
 
 def release_zoom(self, event):
Modified: branches/transforms/lib/matplotlib/backends/backend_agg.py
===================================================================
--- branches/transforms/lib/matplotlib/backends/backend_agg.py	2007年10月03日 23:05:30 UTC (rev 3911)
+++ branches/transforms/lib/matplotlib/backends/backend_agg.py	2007年10月04日 17:21:26 UTC (rev 3912)
@@ -96,15 +96,6 @@
 The renderer handles all the drawing primitives using a graphics
 context instance that controls the colors/styles
 """
- # MGDTODO: Renderers seem to get created and destroyed fairly
- # often so the paths are cached at the class (not instance) level.
- # However, this dictionary is only directly used by RendererBase,
- # so it seems funny to define it here. However, if we didn't, the
- # native paths would be shared across renderers, which is
- # obviously bad. Seems like a good use of metaclasses, but that
- # also seems like a heavy solution for a minor problem.
- _native_paths = weakref.WeakKeyDictionary()
- 
 debug=1
 texd = {} # a cache of tex image rasters
 def __init__(self, width, height, dpi):
@@ -130,12 +121,10 @@
 if __debug__: verbose.report('RendererAgg.__init__ done',
 'debug-annoying')
 
- # MGDTODO: Just adding helpful asserts. This can be removed in the future
 def draw_path(self, gc, path, trans, rgbFace=None):
 assert trans.is_affine
 self._renderer.draw_path(gc, path, trans.frozen(), rgbFace)
 
- # MGDTODO: Just adding helpful asserts. This can be removed in the future
 def draw_markers(self, gc, marker_path, marker_trans, path, trans, rgbFace=None):
 assert marker_trans.is_affine
 assert trans.is_affine
Modified: branches/transforms/lib/matplotlib/legend.py
===================================================================
--- branches/transforms/lib/matplotlib/legend.py	2007年10月03日 23:05:30 UTC (rev 3911)
+++ branches/transforms/lib/matplotlib/legend.py	2007年10月04日 17:21:26 UTC (rev 3912)
@@ -256,10 +256,10 @@
 bboxesText = [t.get_window_extent(renderer) for t in self.texts]
 bboxesHandles = [h.get_window_extent(renderer) for h in self.legendHandles if h is not None]
 
-
 bboxesAll = bboxesText
 bboxesAll.extend(bboxesHandles)
 bbox = Bbox.union(bboxesAll)
+ 
 self.save = bbox
 
 ibox = bbox.inverse_transformed(self.get_transform())
@@ -558,7 +558,7 @@
 handle.set_height(h/2)
 
 # Set the data for the legend patch
- bbox = copy.copy(self._get_handle_text_bbox(renderer))
+ bbox = self._get_handle_text_bbox(renderer).frozen()
 
 bbox = bbox.expanded(1 + self.pad, 1 + self.pad)
 l, b, w, h = bbox.bounds
Modified: branches/transforms/lib/matplotlib/lines.py
===================================================================
--- branches/transforms/lib/matplotlib/lines.py	2007年10月03日 23:05:30 UTC (rev 3911)
+++ branches/transforms/lib/matplotlib/lines.py	2007年10月04日 17:21:26 UTC (rev 3912)
@@ -393,7 +393,6 @@
 def recache(self):
 #if self.axes is None: print 'recache no axes'
 #else: print 'recache units', self.axes.xaxis.units, self.axes.yaxis.units
-	# MGDTODO: Deal with units
 x = ma.asarray(self.convert_xunits(self._xorig), float)
 y = ma.asarray(self.convert_yunits(self._yorig), float)
 
@@ -414,12 +413,12 @@
 	self._x = self._xy[:, 0] # just a view
 	self._y = self._xy[:, 1] # just a view
 self._logcache = None
+
 # Masked arrays are now handled by the Path class itself
 self._path = Path(self._xy, closed=False)
 self._transformed_path = TransformedPath(self._path, self.get_transform())
- # MGDTODO: If _draw_steps is removed, remove the following line also
- self._step_path = None
 
+
 def set_transform(self, t):
 """
 set the Transformation instance used by this artist
@@ -434,47 +433,8 @@
 if len(x)<2: return 1
 return npy.alltrue(x[1:]-x[0:-1]>=0)
 
- # MGDTODO: Remove me (seems to be used for old-style interface only)
- def _get_plottable(self):
- # If log scale is set, only pos data will be returned
-
- x, y = self._x, self._y
-
-	# MGDTODO: (log-scaling)
-	
-# try: logx = self.get_transform().get_funcx().get_type()==LOG10
-# except RuntimeError: logx = False # non-separable
-
-# try: logy = self.get_transform().get_funcy().get_type()==LOG10
-# except RuntimeError: logy = False # non-separable
-
- if True:
- return x, y
-
- if self._logcache is not None:
- waslogx, waslogy, xcache, ycache = self._logcache
- if logx==waslogx and waslogy==logy:
- return xcache, ycache
-
- Nx = len(x)
- Ny = len(y)
-
- if logx: indx = npy.greater(x, 0)
- else: indx = npy.ones(len(x))
-
- if logy: indy = npy.greater(y, 0)
- else: indy = npy.ones(len(y))
-
- ind, = npy.nonzero(npy.logical_and(indx, indy))
- x = npy.take(x, ind)
- y = npy.take(y, ind)
-
- self._logcache = logx, logy, x, y
- return x, y
-
-
 def draw(self, renderer):
- #renderer.open_group('line2d')
+ renderer.open_group('line2d')
 
 if not self._visible: return
 self._newstyle = hasattr(renderer, 'draw_markers')
@@ -498,7 +458,6 @@
 lineFunc = getattr(self, funcname)
 lineFunc(renderer, gc, *self._transformed_path.get_transformed_path_and_affine())
 	 
-	# MGDTODO: Deal with markers
 if self._marker is not None:
 gc = renderer.new_gc()
 self._set_gc_clip(gc)
@@ -509,7 +468,7 @@
 markerFunc = getattr(self, funcname)
 markerFunc(renderer, gc, *self._transformed_path.get_transformed_path_and_affine())
 
- #renderer.close_group('line2d')
+ renderer.close_group('line2d')
 
 def get_antialiased(self): return self._antialiased
 def get_color(self): return self._color
@@ -694,29 +653,7 @@
 def _draw_nothing(self, *args, **kwargs):
 pass
 
-
- def _draw_steps(self, renderer, gc, path):
- # We generate the step function path on-the-fly, and then cache it.
- # The cache may be later invalidated when the data changes
- # (in self.recache())
-
- # MGDTODO: Untested -- using pylab.step doesn't actually trigger
- # this code -- the path is "stepped" before even getting to this
- # class. Perhaps this should be removed here, since it is not as
- # powerful as what is in axes.step() anyway.
- if self._step_path is None:
- vertices = self._path.vertices
- codes = self._path.codes
- siz = len(vertices)
- if siz<2: return
- new_vertices = npy.zeros((2*siz, 2), vertices.dtype)
- new_vertices[0:-1:2, 0], new_vertices[1:-1:2, 0], newvertices[-1, 0] = vertices[:, 0], vertices[1:, 0], vertices[-1, 0]
- new_vertices[0:-1:2, 1], new_vertices[1::2, 1] = vertices[:, 1], vertices[:, 1]
- self._step_path = Path(new_vertices, closed=False)
- gc.set_linestyle('solid')
-	renderer.draw_path(gc, self._step_path, self.get_transform())
-
- 
+ 
 def _draw_solid(self, renderer, gc, path, trans):
 gc.set_linestyle('solid')
 	renderer.draw_path(gc, path, trans)
Modified: branches/transforms/lib/matplotlib/patches.py
===================================================================
--- branches/transforms/lib/matplotlib/patches.py	2007年10月03日 23:05:30 UTC (rev 3911)
+++ branches/transforms/lib/matplotlib/patches.py	2007年10月04日 17:21:26 UTC (rev 3912)
@@ -12,8 +12,6 @@
 import matplotlib.mlab as mlab
 import matplotlib.artist as artist
 from matplotlib.path import Path
-# MGDTODO: Maybe this belongs elsewhere
-from matplotlib.backends._backend_agg import point_in_path
 
 # these are not available for the object inspector until after the
 # class is build so we define an initial set here for the init
@@ -93,8 +91,8 @@
 # method.
 	if callable(self._contains): return self._contains(self,mouseevent)
 
- inside = point_in_path(mouseevent.x, mouseevent.y, self.get_path(),
- self.get_transform().frozen())
+ inside = self.get_path().contains_point(
+ (mouseevent.x, mouseevent.y), self.get_transform())
 return inside, {}
 
 def update_from(self, other):
@@ -236,8 +234,8 @@
 
 
 def get_window_extent(self, renderer=None):
- trans_path = self.get_path().transformed(self.get_path_transform())
- return Bbox.unit().update_from_data(trans_path.vertices)
+ return Bbox.from_lbrt(
+ get_path_extents(self.get_path(), self.get_patch_transform()))
 
 
 def set_lw(self, val):
@@ -341,7 +339,9 @@
 
 Patch.__init__(self, **kwargs)
 
-	self._bbox = transforms.Bbox.from_lbwh(xy[0], xy[1], width, height)
+ left, right = self.convert_xunits((xy[0], xy[0] + width))
+ bottom, top = self.convert_yunits((xy[1], xy[1] + height))
+	self._bbox = transforms.Bbox.from_lbrt(left, bottom, right, top)
 	self._rect_transform = transforms.BboxTransform(
 	 transforms.Bbox.unit(), self._bbox)
 __init__.__doc__ = cbook.dedent(__init__.__doc__) % artist.kwdocd
@@ -352,10 +352,6 @@
 """
 	return Path.unit_rectangle()
 
- # MGDTODO: Convert units
-# left, right = self.convert_xunits((x, x + self.width))
-# bottom, top = self.convert_yunits((y, y + self.height))
-
 def get_patch_transform(self):
 	return self._rect_transform
 
Modified: branches/transforms/lib/matplotlib/path.py
===================================================================
--- branches/transforms/lib/matplotlib/path.py	2007年10月03日 23:05:30 UTC (rev 3911)
+++ branches/transforms/lib/matplotlib/path.py	2007年10月04日 17:21:26 UTC (rev 3912)
@@ -1,3 +1,9 @@
+"""
+Contains a class for managing paths (polylines).
+
+October 2007 Michael Droettboom
+"""
+
 import math
 
 import numpy as npy
@@ -3,7 +9,47 @@
 from numpy import ma as ma
 
+from matplotlib.backends._backend_agg import point_in_path, get_path_extents
+from matplotlib.cbook import simple_linear_interpolation
+
 KAPPA = 4.0 * (npy.sqrt(2) - 1) / 3.0
 
 class Path(object):
+ """
+ Path represents a series of possibly disconnected, possibly
+ closed, line and curve segments.
+
+ The underlying storage is made up of two parallel numpy arrays:
+ vertices: an Nx2 float array of vertices
+ codes: an N-length uint8 array of vertex types
+
+ These two arrays always have the same length in the first
+ dimension. Therefore, to represent a cubic curve, you must
+ provide three vertices as well as three codes "CURVE3".
+
+ The code types are:
+
+ STOP : 1 vertex (ignored)
+ A marker for the end of the entire path (currently not
+ required and ignored)
+
+ MOVETO : 1 vertex
+ Pick up the pen and move to the given vertex.
+ 
+ LINETO : 1 vertex
+ Draw a line from the current position to the given vertex.
+ 
+ CURVE3 : 1 control point, 1 endpoint
+ Draw a quadratic Bezier curve from the current position,
+ with the given control point, to the given end point.
+
+ CURVE4 : 2 control points, 1 endpoint
+ Draw a cubic Bezier curve from the current position, with
+ the given control points, to the given end point.
+
+ CLOSEPOLY : 1 vertex (ignored)
+ Draw a line segment to the start point of the current
+ polyline.
+ """
+ 
 # Path codes
 STOP = 0 # 1 vertex
@@ -13,19 +59,31 @@
 CURVE3 = 3 # 2 vertices
 CURVE4 = 4 # 3 vertices
 CLOSEPOLY = 5 # 1 vertex
- ###
- # MGDTODO: I'm not sure these are supported by PS/PDF/SVG,
- # so if they don't, we probably shouldn't
- CURVEN = 6
- CATROM = 7
- UBSPLINE = 8
- ####
 
 NUM_VERTICES = [1, 1, 1, 2, 3, 1]
 
 code_type = npy.uint8
 
 def __init__(self, vertices, codes=None, closed=True):
+ """
+ Create a new path with the given vertices and codes.
+
+ vertices is an Nx2 numpy float array.
+
+ codes is an N-length numpy array of type Path.code_type.
+
+ See the docstring of Path for a description of the various
+ codes.
+
+ These two arrays must have the same length in the first
+ dimension.
+
+ If codes is None, vertices will be treated as a series of line
+ segments. Additionally, if closed is also True, the polyline
+ will closed. If vertices contains masked values, the
+ resulting path will be compressed, with MOVETO codes inserted
+ in the correct places to jump over the masked regions.
+ """
 vertices = ma.asarray(vertices, npy.float_)
 
 	if codes is None:
@@ -82,6 +140,11 @@
 vertices = property(_get_vertices)
 
 def iter_endpoints(self):
+ """
+ Iterates over all of the endpoints in the path. Unlike
+ iterating directly over the vertices array, curve control
+ points are skipped over.
+ """
 	i = 0
 	NUM_VERTICES = self.NUM_VERTICES
 	vertices = self.vertices
@@ -95,11 +158,57 @@
 i += 1
 
 def transformed(self, transform):
+ """
+ Return a transformed copy of the path.
+
+ See transforms.TransformedPath for a path that will cache the
+ transformed result and automatically update when the transform
+ changes.
+ """
 return Path(transform.transform(self.vertices), self.codes)
- 
+
+ def contains_point(self, point, transform=None):
+ """
+ Returns True if the path contains the given point.
+
+ If transform is not None, the path will be transformed before
+ performing the test.
+ """
+ if transform is None:
+ from transforms import IdentityTransform
+ transform = IdentityTransform
+ return point_in_path(point[0], point[1], self, transform.frozen())
+
+ def get_extents(self, transform=None):
+ """
+ Returns the extents (xmin, ymin, xmax, ymax) of the path.
+
+ Unlike computing the extents on the vertices alone, this
+ algorithm will take into account the curves and deal with
+ control points appropriately.
+ """
+ from transforms import Bbox, IdentityTransform
+ if transform is None:
+ transform = IdentityTransform
+ return Bbox.from_lbrt(*get_path_extents(self, transform))
+
+ def interpolated(self, steps):
+ """
+ Returns a new path resampled to length N x steps.
+ Does not currently handle interpolating curves.
+ """
+ vertices = simple_linear_interpolation(self.vertices, steps)
+ codes = self.codes
+ new_codes = Path.LINETO * npy.ones(((len(codes) - 1) * steps + 1, ))
+ new_codes[0::steps] = codes
+ return Path(vertices, new_codes)
+ 
 _unit_rectangle = None
 #@classmethod
 def unit_rectangle(cls):
+ """
+ Returns a Path of the unit rectangle from (0, 0) to (1, 1).
+ """
 	if cls._unit_rectangle is None:
 	 cls._unit_rectangle = \
 		Path([[0.0, 0.0], [1.0, 0.0], [1.0, 1.0], [0.0, 1.0]])
@@ -109,9 +218,14 @@
 _unit_regular_polygons = {}
 #@classmethod
 def unit_regular_polygon(cls, numVertices):
+ """
+ Returns a Path for a unit regular polygon with the given
+ numVertices and radius of 1.0, centered at (0, 0).
+ """
 	path = cls._unit_regular_polygons.get(numVertices)
 	if path is None:
-	 theta = 2*npy.pi/numVertices * npy.arange(numVertices).reshape((numVertices, 1))
+	 theta = (2*npy.pi/numVertices *
+ npy.arange(numVertices).reshape((numVertices, 1)))
 	 # This initial rotation is to make sure the polygon always
 # "points-up"
 	 theta += npy.pi / 2.0
@@ -124,6 +238,10 @@
 _unit_circle = None
 #@classmethod
 def unit_circle(cls):
+ """
+ Returns a Path of the unit circle. The circle is approximated
+ using cubic Bezier curves.
+ """
 	if cls._unit_circle is None:
 offset = KAPPA
 	 vertices = npy.array(
@@ -158,6 +276,10 @@
 
 #@classmethod
 def arc(cls, theta1, theta2, is_wedge=False):
+ """
+ Returns an arc on the unit circle from angle theta1 to angle
+ theta2 (in degrees).
+ """
 # From Masionobe, L. 2003. "Drawing an elliptical arc using
 # polylines, quadratic or cubic Bezier curves".
 #
@@ -234,5 +356,9 @@
 arc = classmethod(arc)
 
 def wedge(cls, theta1, theta2):
+ """
+ Returns a wedge of the unit circle from angle theta1 to angle
+ theta2 (in degrees).
+ """
 return cls.arc(theta1, theta2, True)
 wedge = classmethod(wedge)
Modified: branches/transforms/lib/matplotlib/projections/polar.py
===================================================================
--- branches/transforms/lib/matplotlib/projections/polar.py	2007年10月03日 23:05:30 UTC (rev 3911)
+++ branches/transforms/lib/matplotlib/projections/polar.py	2007年10月04日 17:21:26 UTC (rev 3912)
@@ -2,9 +2,12 @@
 
 import numpy as npy
 
+from matplotlib.artist import kwdocd
 from matplotlib.axes import Axes
+from matplotlib import cbook
 from matplotlib.patches import Circle
-from matplotlib.ticker import Locator
+from matplotlib.path import Path
+from matplotlib.ticker import Formatter, Locator
 from matplotlib.transforms import Affine2D, Affine2DBase, Bbox, BboxTransform, \
 IdentityTransform, Transform, TransformWrapper
 
@@ -16,6 +19,10 @@
 output_dims = 2
 is_separable = False
 
+ def __init__(self, resolution):
+ Transform.__init__(self)
+ self._resolution = resolution
+
 def transform(self, tr):
 xy = npy.zeros(tr.shape, npy.float_)
 t = tr[:, 0:1]
@@ -27,6 +34,12 @@
 return xy
 transform_non_affine = transform
 
+ def transform_path(self, path):
+ if len(path.vertices) == 2:
+ path = path.interpolated(self._resolution)
+ return Path(self.transform(path.vertices), path.codes)
+ transform_path_non_affine = transform_path
+ 
 def inverted(self):
 return PolarAxes.InvertedPolarTransform()
 
@@ -64,10 +77,35 @@
 def inverted(self):
 return PolarAxes.PolarTransform()
 
- class ThetaLocator(Locator):
- pass
+ class ThetaFormatter(Formatter):
+ def __call__(self, x, pos=None):
+ return u"%d\u00b0" % ((x / npy.pi) * 180.0)
+
+ class RadialLocator(Locator):
+ def __init__(self, base):
+ self.base = base
+
+ def __call__(self):
+ ticks = self.base()
+ # MGDTODO: Use numpy
+ return [x for x in ticks if x > 0]
+
+ def autoscale(self):
+ return self.base.autoscale()
+
+ def pan(self, numsteps):
+ return self.base.pan(numsteps)
+
+ def zoom(self, direction):
+ return self.base.zoom(direction)
+
+ def refresh(self):
+ return self.base.refresh()
+
+ RESOLUTION = 100
 
 def __init__(self, *args, **kwargs):
+ self._rpad = 0.05
 Axes.__init__(self, *args, **kwargs)
 self.set_aspect('equal', adjustable='box', anchor='C')
 self.cla()
@@ -76,55 +114,105 @@
 def cla(self):
 Axes.cla(self)
 
- self.xaxis.set_major_locator(PolarAxes.ThetaLocator())
- 
- def _set_transData(self):
+ self.xaxis.set_major_formatter(self.ThetaFormatter())
+ angles = npy.arange(0.0, 360.0, 45.0)
+ self.set_thetagrids(angles)
+ self.yaxis.set_major_locator(self.RadialLocator(self.yaxis.get_major_locator()))
+
+ def _set_lim_and_transforms(self):
+	self.dataLim = Bbox([[0.0, 0.0], [npy.pi * 2.0, 1.0]])
+ self.viewLim = Bbox.unit()
+ self.transAxes = BboxTransform(Bbox.unit(), self.bbox)
+
+ # Transforms the x and y axis separately by a scale factor
+ # It is assumed that this part will have non-linear components
+ self.transScale = TransformWrapper(IdentityTransform())
+
 # A (possibly non-linear) projection on the (already scaled) data
- self.transProjection = self.PolarTransform()
+ self.transProjection = self.PolarTransform(self.RESOLUTION)
 
 # An affine transformation on the data, generally to limit the
 # range of the axes
 self.transProjectionAffine = self.PolarAffine(self.viewLim)
 
 self.transData = self.transScale + self.transProjection + \
- self.transProjectionAffine + self.transAxes
+ (self.transProjectionAffine + self.transAxes)
 
 self._xaxis_transform = (
- self.PolarTransform() +
+ self.transProjection +
 self.PolarAffine(Bbox.unit()) +
 self.transAxes)
+ self._theta_label1_position = Affine2D().translate(0.0, 1.1)
+ self._xaxis_text1_transform = (
+ self._theta_label1_positi...
 
[truncated message content]
1 2 3 .. 5 > >> (Page 1 of 5)
Want the latest updates on software, tech news, and AI?
Get latest updates about software, tech news, and AI from SourceForge directly in your inbox once a month.
Thanks for helping keep SourceForge clean.
X





Briefly describe the problem (required):
Upload screenshot of ad (required):
Select a file, or drag & drop file here.
Screenshot instructions:

Click URL instructions:
Right-click on the ad, choose "Copy Link", then paste here →
(This may not be possible with some types of ads)

More information about our ad policies

Ad destination/click URL:

AltStyle によって変換されたページ (->オリジナル) /