Revision: 4787
http://matplotlib.svn.sourceforge.net/matplotlib/?rev=4787&view=rev
Author: mdboom
Date: 2007-12-21 11:40:59 -0800 (Fri, 21 Dec 2007)
Log Message:
-----------
Merged revisions 4773-4785 via svnmerge from
http://matplotlib.svn.sf.net/svnroot/matplotlib/trunk/matplotlib
........
r4783 | mdboom | 2007-12-21 10:08:38 -0500 (Fri, 21 Dec 2007) | 2 lines
Add size-dependent highly-accurate arc drawing.
........
r4785 | jdh2358 | 2007-12-21 11:22:42 -0500 (Fri, 21 Dec 2007) | 2 lines
added unit support to arc
........
Modified Paths:
--------------
branches/transforms/API_CHANGES
branches/transforms/CODING_GUIDE
branches/transforms/examples/units/ellipse_with_units.py
branches/transforms/lib/matplotlib/axes.py
branches/transforms/lib/matplotlib/legend.py
branches/transforms/lib/matplotlib/mlab.py
branches/transforms/lib/matplotlib/patches.py
branches/transforms/unit/ellipse_large.py
Property Changed:
----------------
branches/transforms/
Property changes on: branches/transforms
___________________________________________________________________
Name: svnmerge-integrated
- /trunk/matplotlib:1-4772
+ /trunk/matplotlib:1-4785
Modified: branches/transforms/API_CHANGES
===================================================================
--- branches/transforms/API_CHANGES 2007-12-21 18:53:29 UTC (rev 4786)
+++ branches/transforms/API_CHANGES 2007-12-21 19:40:59 UTC (rev 4787)
@@ -169,6 +169,9 @@
END OF TRANSFORMS REFACTORING
+ For csv2rec, checkrows=0 is the new default indicating all rows
+ will be checked for type inference
+
A warning is issued when an image is drawn on log-scaled
axes, since it will not log-scale the image data.
Modified: branches/transforms/CODING_GUIDE
===================================================================
--- branches/transforms/CODING_GUIDE 2007-12-21 18:53:29 UTC (rev 4786)
+++ branches/transforms/CODING_GUIDE 2007-12-21 19:40:59 UTC (rev 4787)
@@ -12,6 +12,9 @@
# checking out the main src
svn co
https://matplotlib.svn.sourceforge.net/svnroot/matplotlib/trunk/matplotlib
matplotlib --username=youruser --password=yourpass
+# branch checkouts, eg the transforms branch
+svn co
https://matplotlib.svn.sourceforge.net/svnroot/matplotlib/branches/transforms
transbranch
+
== Committing changes ==
When committing changes to matplotlib, there are a few things to bear
@@ -27,12 +30,6 @@
support 2.3, so avoid 2.4 only features like decorators until we
remove 2.3 support
- * Are your changes Numeric, numarray and numpy compatible? Try
- running simple_plot.py or image_demo.py with --Numeric, --numarray
- and --numpy (Note, someone should add examples to
- backend_driver.py which explicitly require numpy, numarray and
- Numeric so we can automatically catch these)
-
* Can you pass examples/backend_driver.py? This is our poor man's
unit test.
@@ -49,9 +46,8 @@
For numpy, use:
import numpy as npy
- ...
a = npy.array([1,2,3])
- ...
+
For masked arrays, use:
import matplotlib.numerix.npyma as ma
@@ -64,16 +60,20 @@
For matplotlib main module, use:
import matplotlib as mpl
- ...
mpl.rcParams['xtick.major.pad'] = 6
-For matplotlib modules, use:
+For matplotlib modules (or any other modules), use:
- import matplotlib.cbook as cbook as mpl_cbook
- ...
- if mpl_cbook.iterable(z):
- ...
+ import matplotlib.cbook as cbook
+
+ if cbook.iterable(z):
+ pass
+ We prefer this over the equivalent 'from matplotlib import cbook'
+ because the latter is ambiguous whether cbook is a module or a
+ function to the new developer. The former makes it explcit that
+ you are importing a module or package.
+
== Naming, spacing, and formatting conventions ==
In general, we want to hew as closely as possible to the standard
@@ -114,15 +114,6 @@
python, C and C++
-When importing modules from the matplotlib namespace
-
- import matplotlib.cbook as cbook # DO
- from matplotlib import cbook #DONT
-
-because the latter is ambiguous whether cbook is a module or a
-function to the new developer. The former makes it explcit that you
-are importing a module or package.
-
; and similarly for c++-mode-hook and c-mode-hook
(add-hook 'python-mode-hook
(lambda ()
Modified: branches/transforms/examples/units/ellipse_with_units.py
===================================================================
--- branches/transforms/examples/units/ellipse_with_units.py 2007-12-21
18:53:29 UTC (rev 4786)
+++ branches/transforms/examples/units/ellipse_with_units.py 2007-12-21
19:40:59 UTC (rev 4787)
@@ -1,5 +1,5 @@
"""
-Compare the ellipse generated with arcs versus a polygonal approximation
+Compare the ellipse generated with arcs versus a polygonal approximation
"""
from basic_units import cm
import numpy as npy
@@ -46,4 +46,24 @@
#fig.savefig('ellipse_compare.png')
fig.savefig('ellipse_compare')
+fig = figure()
+ax = fig.add_subplot(211, aspect='auto')
+ax.fill(x, y, alpha=0.2, facecolor='yellow', edgecolor='yellow', linewidth=1,
zorder=1)
+
+e1 = patches.Arc((xcenter, ycenter), width, height,
+ angle=angle, linewidth=2, fill=False, zorder=2)
+
+ax.add_patch(e1)
+
+ax = fig.add_subplot(212, aspect='equal')
+ax.fill(x, y, alpha=0.2, facecolor='green', edgecolor='green', zorder=1)
+e2 = patches.Arc((xcenter, ycenter), width, height,
+ angle=angle, linewidth=2, fill=False, zorder=2)
+
+
+ax.add_patch(e2)
+
+#fig.savefig('arc_compare.png')
+fig.savefig('arc_compare')
+
show()
Modified: branches/transforms/lib/matplotlib/axes.py
===================================================================
--- branches/transforms/lib/matplotlib/axes.py 2007-12-21 18:53:29 UTC (rev
4786)
+++ branches/transforms/lib/matplotlib/axes.py 2007-12-21 19:40:59 UTC (rev
4787)
@@ -321,6 +321,8 @@
ret.append(seg)
def makefill(x, y):
+ x = self.axes.convert_xunits(x)
+ y = self.axes.convert_yunits(y)
facecolor = self._get_next_cycle_color()
seg = mpatches.Polygon(zip(x, y),
facecolor = facecolor,
@@ -363,6 +365,8 @@
def makefill(x, y):
facecolor = color
+ x = self.axes.convert_xunits(x)
+ y = self.axes.convert_yunits(y)
seg = mpatches.Polygon(zip(x, y),
facecolor = facecolor,
fill=True,
Modified: branches/transforms/lib/matplotlib/legend.py
===================================================================
--- branches/transforms/lib/matplotlib/legend.py 2007-12-21 18:53:29 UTC
(rev 4786)
+++ branches/transforms/lib/matplotlib/legend.py 2007-12-21 19:40:59 UTC
(rev 4787)
@@ -140,7 +140,7 @@
self._offsetTransform = Affine2D()
self._parentTransform = BboxTransformTo(parent.bbox)
Artist.set_transform(self, self._offsetTransform +
self._parentTransform)
-
+
if loc is None:
loc = rcParams["legend.loc"]
if not self.isaxes and loc in [0,'best']:
@@ -226,7 +226,7 @@
bboxesAll = bboxesText
bboxesAll.extend(bboxesHandles)
bbox = Bbox.union(bboxesAll)
-
+
self.save = bbox
ibox = bbox.inverse_transformed(self.get_transform())
@@ -328,7 +328,7 @@
if isinstance(handle, Rectangle):
transform = handle.get_data_transform() + inverse_transform
- bboxes.append(handle._bbox.transformed(transform))
+ bboxes.append(handle.get_bbox().transformed(transform))
else:
transform = handle.get_transform() + inverse_transform
bboxes.append(handle.get_path().get_extents(transform))
@@ -499,7 +499,7 @@
bbox = bbox.expanded(1 + self.pad, 1 + self.pad)
l, b, w, h = bbox.bounds
self.legendPatch.set_bounds(l, b, w, h)
-
+
ox, oy = 0, 0 # center
if iterable(self._loc) and len(self._loc)==2:
Modified: branches/transforms/lib/matplotlib/mlab.py
===================================================================
--- branches/transforms/lib/matplotlib/mlab.py 2007-12-21 18:53:29 UTC (rev
4786)
+++ branches/transforms/lib/matplotlib/mlab.py 2007-12-21 19:40:59 UTC (rev
4787)
@@ -2045,7 +2045,7 @@
return newrec.view(npy.recarray)
-def csv2rec(fname, comments='#', skiprows=0, checkrows=5, delimiter=',',
+def csv2rec(fname, comments='#', skiprows=0, checkrows=0, delimiter=',',
converterd=None, names=None, missing=None):
"""
Load data from comma/space/tab delimited file in fname into a
@@ -2075,7 +2075,7 @@
names, if not None, is a list of header names. In this case, no
header will be read from the file
- if no rows are found, None is returned See examples/loadrec.py
+ if no rows are found, None is returned -- see examples/loadrec.py
"""
if converterd is None:
Modified: branches/transforms/lib/matplotlib/patches.py
===================================================================
--- branches/transforms/lib/matplotlib/patches.py 2007-12-21 18:53:29 UTC
(rev 4786)
+++ branches/transforms/lib/matplotlib/patches.py 2007-12-21 19:40:59 UTC
(rev 4787)
@@ -366,10 +366,11 @@
Patch.__init__(self, **kwargs)
- 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_extents(left, bottom, right, top)
- self._rect_transform = transforms.BboxTransformTo(self._bbox)
+ self._x = xy[0]
+ self._y = xy[1]
+ self._width = width
+ self._height = height
+ self._rect_transform = transforms.IdentityTransform()
__init__.__doc__ = cbook.dedent(__init__.__doc__) % artist.kwdocd
def get_path(self):
@@ -378,6 +379,19 @@
"""
return Path.unit_rectangle()
+ def _update_patch_transform(self):
+ x = self.convert_xunits(self._x)
+ y = self.convert_yunits(self._y)
+ width = self.convert_xunits(self._width)
+ height = self.convert_yunits(self._height)
+ bbox = transforms.Bbox.from_bounds(x, y, width, height)
+ self._rect_transform = transforms.BboxTransformTo(bbox)
+ self._combined_transform = self._rect_transform +
artist.Artist.get_transform(self)
+
+ def draw(self, renderer):
+ self._update_patch_transform()
+ Patch.draw(self, renderer)
+
def get_patch_transform(self):
return self._rect_transform
@@ -388,19 +402,19 @@
def get_x(self):
"Return the left coord of the rectangle"
- return self._bbox.x0
+ return self._x
def get_y(self):
"Return the bottom coord of the rectangle"
- return self._bbox.y0
+ return self._y
def get_width(self):
"Return the width of the rectangle"
- return self._bbox.width
+ return self._width
def get_height(self):
"Return the height of the rectangle"
- return self._bbox.height
+ return self._height
def set_x(self, x):
"""
@@ -408,9 +422,7 @@
ACCEPTS: float
"""
- w = self._bbox.width
- x = self.convert_xunits(x)
- self._bbox.intervalx = (x, x + w)
+ self._x = x
def set_y(self, y):
"""
@@ -418,9 +430,7 @@
ACCEPTS: float
"""
- h = self._bbox.height
- y = self.convert_yunits(y)
- self._bbox.intervaly = (y, y + h)
+ self._y = y
def set_width(self, w):
"""
@@ -428,8 +438,7 @@
ACCEPTS: float
"""
- w = self.convert_xunits(w)
- self._bbox.x1 = self._bbox.x0 + w
+ self._width = w
def set_height(self, h):
"""
@@ -437,8 +446,7 @@
ACCEPTS: float
"""
- h = self.convert_yunits(h)
- self._bbox.y1 = self._bbox.y0 + h
+ self._height = h
def set_bounds(self, *args):
"""
@@ -450,10 +458,13 @@
l,b,w,h = args[0]
else:
l,b,w,h = args
- l, w = self.convert_xunits((l, w))
- b, h = self.convert_yunits((b, h))
- self._bbox.bounds = l,b,w,h
+ self._x = l
+ self._y = b
+ self._width = w
+ self._height = h
+ def get_bbox(self):
+ return transforms.Bbox.from_bounds(self._x, self._y, self._width,
self._height)
class RegularPolygon(Patch):
"""
@@ -494,7 +505,6 @@
def _get_xy(self):
return self._xy
def _set_xy(self, xy):
- self._xy = xy
self._update_transform()
xy = property(_get_xy, _set_xy)
@@ -588,9 +598,23 @@
"""
Patch.__init__(self, **kwargs)
- self._path = Path.wedge(theta1, theta2)
+ self.center = center
+ self.r = r
+ self.theta1 = theta1
+ self.theta2 = theta2
+ self._patch_transform = transforms.IdentityTransform()
+ self._path = Path.wedge(self.theta1, self.theta2)
+
+ def draw(self, renderer):
+ x = self.convert_xunits(self.center[0])
+ y = self.convert_yunits(self.center[1])
+ rx = self.convert_xunits(self.r)
+ ry = self.convert_yunits(self.r)
self._patch_transform = transforms.Affine2D() \
- .scale(r).translate(*center)
+ .scale(rx, ry).translate(x, y)
+ self._combined_transform = self._patch_transform + \
+ artist.Artist.get_transform(self)
+ Patch.draw(self, renderer)
__init__.__doc__ = cbook.dedent(__init__.__doc__) % artist.kwdocd
def get_path(self):
@@ -806,8 +830,6 @@
%(Patch)s
"""
- self.center = xy
- self.radius = radius
RegularPolygon.__init__(self, xy,
resolution,
radius,
@@ -821,7 +843,7 @@
A scale-free ellipse
"""
def __str__(self):
- return
"Ellipse(%d,%d;%dx%d)"%(self.center[0],self.center[1],self.width,self.height)
+ return
"Ellipse(%s,%s;%sx%s)"%(self.center[0],self.center[1],self.width,self.height)
def __init__(self, xy, width, height, angle=0.0, **kwargs):
"""
@@ -835,18 +857,28 @@
"""
Patch.__init__(self, **kwargs)
- self._center = xy
- self._width, self._height = width, height
- self._angle = angle
- self._recompute_transform()
+ self.center = xy
+ self.width, self.height = width, height
+ self.angle = angle
self._path = Path.unit_circle()
+ self._patch_transform = transforms.IdentityTransform()
def _recompute_transform(self):
+ center = (self.convert_xunits(self.center[0]),
+ self.convert_yunits(self.center[1]))
+ width = self.convert_xunits(self.width)
+ height = self.convert_yunits(self.height)
self._patch_transform = transforms.Affine2D() \
- .scale(self._width * 0.5, self._height * 0.5) \
- .rotate_deg(self._angle) \
- .translate(*self._center)
+ .scale(width * 0.5, height * 0.5) \
+ .rotate_deg(self.angle) \
+ .translate(*center)
+ self._combined_transform = self._patch_transform + \
+ artist.Artist.get_transform(self)
+ def draw(self, renderer):
+ self._recompute_transform()
+ Patch.draw(self, renderer)
+
def get_path(self):
"""
Return the vertices of the rectangle
@@ -861,27 +893,7 @@
x, y = self.get_transform().inverted().transform_point((ev.x, ev.y))
return (x*x + y*y) <= 1.0, {}
- def _get_center(self):
- return self._center
- def _set_center(self, center):
- self._center = center
- self._recompute_transform()
- center = property(_get_center, _set_center)
- def _get_xy(self):
- return self._xy
- def _set_xy(self, xy):
- self._xy = xy
- self._recompute_transform()
- xy = property(_get_xy, _set_xy)
-
- def _get_angle(self):
- return self._angle
- def _set_angle(self, angle):
- self._angle = angle
- self._recompute_transform()
- angle = property(_get_angle, _set_angle)
-
class Circle(Ellipse):
"""
A circle patch
@@ -912,9 +924,14 @@
"""
An elliptical arc. Because it performs various optimizations, it
can not be filled.
+
+ The arc must be used in an Axes instance it cannot be added
+ directly to a Figure) because it is optimized to only render the
+ segments that are inside the axes bounding box with high
+ resolution.
"""
def __str__(self):
- return
"Arc(%d,%d;%dx%d)"%(self.center[0],self.center[1],self.width,self.height)
+ return
"Arc(%s,%s;%sx%s)"%(self.center[0],self.center[1],self.width,self.height)
def __init__(self, xy, width, height, angle=0.0, theta1=0.0, theta2=360.0,
**kwargs):
"""
@@ -938,8 +955,8 @@
Ellipse.__init__(self, xy, width, height, angle, **kwargs)
- self._theta1 = theta1
- self._theta2 = theta2
+ self.theta1 = theta1
+ self.theta2 = theta2
def draw(self, renderer):
"""
@@ -984,13 +1001,20 @@
pairs of vertices are drawn using the bezier arc
approximation technique implemented in Path.arc().
"""
+ if not hasattr(self, 'axes'):
+ raise RuntimeError('Arcs can only be used in Axes instances')
+
+ self._recompute_transform()
+
# Get the width and height in pixels
+ width = self.convert_xunits(self.width)
+ height = self.convert_yunits(self.height)
width, height = self.get_transform().transform_point(
- (self._width, self._height))
- inv_error = (1.0 / 1.89818e-6)
+ (width, height))
+ inv_error = (1.0 / 1.89818e-6) * 0.5
if width < inv_error and height < inv_error:
- self._path = Path.arc(self._theta1, self._theta2)
+ self._path = Path.arc(self.theta1, self.theta2)
return Patch.draw(self, renderer)
def iter_circle_intersect_on_line(x0, y0, x1, y1):
@@ -1037,7 +1061,6 @@
if x >= x0e and x <= x1e and y >= y0e and y <= y1e:
yield x, y
-
# Transforms the axes box_path so that it is relative to the unit
# circle in the same way that it is relative to the desired
# ellipse.
@@ -1050,8 +1073,8 @@
TWOPI = PI * 2.0
RAD2DEG = 180.0 / PI
DEG2RAD = PI / 180.0
- theta1 = self._theta1
- theta2 = self._theta2
+ theta1 = self.theta1
+ theta2 = self.theta2
thetas = {}
# For each of the point pairs, there is a line segment
for p0, p1 in zip(box_path.vertices[:-1], box_path.vertices[1:]):
Modified: branches/transforms/unit/ellipse_large.py
===================================================================
--- branches/transforms/unit/ellipse_large.py 2007-12-21 18:53:29 UTC (rev
4786)
+++ branches/transforms/unit/ellipse_large.py 2007-12-21 19:40:59 UTC (rev
4787)
@@ -6,7 +6,7 @@
import math
from pylab import *
-from matplotlib.patches import Arc
+from matplotlib.patches import Ellipse, Arc
# given a point x, y
x = 2692.440
@@ -47,39 +47,75 @@
ellipseLine = ax.plot( xs, ys, **kwargs )
+
+
##################################################
# make the axes
-ax = subplot( 211, aspect='equal' )
-ax.set_aspect( 'equal', 'datalim' )
+ax1 = subplot( 311, aspect='equal' )
+ax1.set_aspect( 'equal', 'datalim' )
# make the lower-bound ellipse
diam = (r - delta) * 2.0
-lower_ellipse = Arc( (0.0, 0.0), diam, diam, 0.0, fill=False,
edgecolor="darkgreen" )
-ax.add_patch( lower_ellipse )
+lower_ellipse = Ellipse( (0.0, 0.0), diam, diam, 0.0, fill=False,
edgecolor="darkgreen" )
+ax1.add_patch( lower_ellipse )
# make the target ellipse
diam = r * 2.0
-target_ellipse = Arc( (0.0, 0.0), diam, diam, 0.0, fill=False,
edgecolor="darkred" )
-ax.add_patch( target_ellipse )
+target_ellipse = Ellipse( (0.0, 0.0), diam, diam, 0.0, fill=False,
edgecolor="darkred" )
+ax1.add_patch( target_ellipse )
# make the upper-bound ellipse
diam = (r + delta) * 2.0
-upper_ellipse = Arc( (0.0, 0.0), diam, diam, 0.0, fill=False,
edgecolor="darkblue" )
-ax.add_patch( upper_ellipse )
+upper_ellipse = Ellipse( (0.0, 0.0), diam, diam, 0.0, fill=False,
edgecolor="darkblue" )
+ax1.add_patch( upper_ellipse )
# make the target
diam = delta * 2.0
+target = Ellipse( (x, y), diam, diam, 0.0, fill=False, edgecolor="#DD1208" )
+ax1.add_patch( target )
+
+# give it a big marker
+ax1.plot( [x], [y], marker='x', linestyle='None', mfc='red', mec='red',
markersize=10 )
+
+##################################################
+# make the axes
+ax = subplot( 312, aspect='equal' , sharex=ax1, sharey=ax1)
+ax.set_aspect( 'equal', 'datalim' )
+
+# make the lower-bound arc
+diam = (r - delta) * 2.0
+lower_arc = Arc( (0.0, 0.0), diam, diam, 0.0, fill=False,
edgecolor="darkgreen" )
+ax.add_patch( lower_arc )
+
+# make the target arc
+diam = r * 2.0
+target_arc = Arc( (0.0, 0.0), diam, diam, 0.0, fill=False, edgecolor="darkred"
)
+ax.add_patch( target_arc )
+
+# make the upper-bound arc
+diam = (r + delta) * 2.0
+upper_arc = Arc( (0.0, 0.0), diam, diam, 0.0, fill=False, edgecolor="darkblue"
)
+ax.add_patch( upper_arc )
+
+# make the target
+diam = delta * 2.0
target = Arc( (x, y), diam, diam, 0.0, fill=False, edgecolor="#DD1208" )
ax.add_patch( target )
# give it a big marker
ax.plot( [x], [y], marker='x', linestyle='None', mfc='red', mec='red',
markersize=10 )
+
+
+
+
##################################################
# now lets do the same thing again using a custom ellipse function
+
+
# make the axes
-ax = subplot( 212, aspect='equal', sharex=ax, sharey=ax )
+ax = subplot( 313, aspect='equal', sharex=ax1, sharey=ax1 )
ax.set_aspect( 'equal', 'datalim' )
# make the lower-bound ellipse
@@ -97,11 +133,17 @@
# give it a big marker
ax.plot( [x], [y], marker='x', linestyle='None', mfc='red', mec='red',
markersize=10 )
+
+# give it a big marker
+ax.plot( [x], [y], marker='x', linestyle='None', mfc='red', mec='red',
markersize=10 )
+
##################################################
# lets zoom in to see the area of interest
-ax.set_xlim(2650, 2735)
-ax.set_ylim(6705, 6735)
+ax1.set_xlim(2650, 2735)
+ax1.set_ylim(6705, 6735)
+
+savefig("ellipse")
show()
-# savefig("ellipse")
+
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