Revision: 3854
http://matplotlib.svn.sourceforge.net/matplotlib/?rev=3854&view=rev
Author: mdboom
Date: 2007-09-17 06:41:38 -0700 (Mon, 17 Sep 2007)
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
+ [EMAIL PROTECTED]
+ 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 = {}
+ [EMAIL PROTECTED]
+ 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
+ [EMAIL PROTECTED]
+ 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.
-------------------------------------------------------------------------
This SF.net email is sponsored by: Microsoft
Defy all challenges. Microsoft(R) Visual Studio 2005.
http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/
_______________________________________________
Matplotlib-checkins mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/matplotlib-checkins