Revision: 3956
http://matplotlib.svn.sourceforge.net/matplotlib/?rev=3956&view=rev
Author: mdboom
Date: 2007-10-16 07:35:12 -0700 (Tue, 16 Oct 2007)
Log Message:
-----------
Merged revisions 3933-3955 via svnmerge from
http://matplotlib.svn.sf.net/svnroot/matplotlib/trunk/matplotlib
........
r3935 | mdboom | 2007-10-11 13:03:50 -0400 (Thu, 11 Oct 2007) | 1 line
Fixed minor import bug
........
r3941 | jdh2358 | 2007-10-14 15:00:50 -0400 (Sun, 14 Oct 2007) | 1 line
added ellipse compare script
........
r3949 | jdh2358 | 2007-10-15 16:00:54 -0400 (Mon, 15 Oct 2007) | 3 lines
fixed an aspect=auto problem with bezier ellipse approx
........
r3950 | jdh2358 | 2007-10-15 16:52:32 -0400 (Mon, 15 Oct 2007) | 2 lines
Fixed a texst clipping bug in backend agg
........
r3951 | jdh2358 | 2007-10-15 17:08:35 -0400 (Mon, 15 Oct 2007) | 2 lines
Fixed an annotation unit bug
........
r3952 | jdh2358 | 2007-10-15 17:22:03 -0400 (Mon, 15 Oct 2007) | 2 lines
fixed a unit problem with annotations
........
r3953 | mdboom | 2007-10-16 08:28:49 -0400 (Tue, 16 Oct 2007) | 1 line
Fix build on Windows with MSVC .NET 2003
........
r3954 | jdh2358 | 2007-10-16 09:45:59 -0400 (Tue, 16 Oct 2007) | 2 lines
restored unit support for ellipses -- and added
examples/units/ellipse_with_units.py
........
Modified Paths:
--------------
branches/transforms/CHANGELOG
branches/transforms/boilerplate.py
branches/transforms/lib/matplotlib/backends/backend_ps.py
branches/transforms/lib/matplotlib/cbook.py
branches/transforms/lib/matplotlib/mlab.py
branches/transforms/lib/matplotlib/patches.py
branches/transforms/lib/matplotlib/text.py
branches/transforms/src/_backend_agg.cpp
branches/transforms/ttconv/ttutil.cpp
branches/transforms/unit/ellipse_compare.py
Added Paths:
-----------
branches/transforms/examples/units/annotate_with_units.py
branches/transforms/examples/units/ellipse_with_units.py
Property Changed:
----------------
branches/transforms/
Property changes on: branches/transforms
___________________________________________________________________
Name: svnmerge-integrated
- /trunk/matplotlib:1-3932
+ /trunk/matplotlib:1-3955
Modified: branches/transforms/CHANGELOG
===================================================================
--- branches/transforms/CHANGELOG 2007-10-16 14:17:53 UTC (rev 3955)
+++ branches/transforms/CHANGELOG 2007-10-16 14:35:12 UTC (rev 3956)
@@ -1,3 +1,12 @@
+2007-10-15 Fixed a bug in patches.Ellipse that was broken for
+ aspect='auto'. Scale free ellipses now work properly for
+ equal and auto on Agg and PS, and they fall back on a
+ polygonal approximation for nonlinear transformations until
+ we convince oursleves that the spline approximation holds
+ for nonlinear transformations. Added
+ unit/ellipse_compare.py to compare spline with vertex
+ approx for both aspects. JDH
+
2007-10-05 remove generator expressions from texmanager and mpltraits.
generator expressions are not supported by python-2.3 - DSD
Modified: branches/transforms/boilerplate.py
===================================================================
--- branches/transforms/boilerplate.py 2007-10-16 14:17:53 UTC (rev 3955)
+++ branches/transforms/boilerplate.py 2007-10-16 14:35:12 UTC (rev 3956)
@@ -2,10 +2,9 @@
# file is pasted into pylab.py. We did try to do this the smart way,
# with callable functions and new.function, but could never get the
# docstrings right for python2.2. See
-#
http://groups-beta.google.com/group/comp.lang.python/messages/1b14640f3a4ad3dc,b3d7453af21e5f82,17739e70ac6f710c,9d5291fce29cbbb1,c5b578e4ffc6af28,056ff270daa2f414?thread_id=dcd63ec13096a0f6&mode=thread
+#
http://groups.google.com/group/comp.lang.python/browse_frm/thread/dcd63ec13096a0f6/1b14640f3a4ad3dc?#1b14640f3a4ad3dc
-
# note we check for __doc__ is not None since py2exe optimize removes
# the docstrings
Copied: branches/transforms/examples/units/annotate_with_units.py (from rev
3954, trunk/matplotlib/examples/units/annotate_with_units.py)
===================================================================
--- branches/transforms/examples/units/annotate_with_units.py
(rev 0)
+++ branches/transforms/examples/units/annotate_with_units.py 2007-10-16
14:35:12 UTC (rev 3956)
@@ -0,0 +1,27 @@
+
+import pylab
+from basic_units import cm
+
+fig = pylab.figure()
+ax = fig.add_subplot(111)
+
+
+ax.annotate( "Note 01", [0.5*cm, 0.5*cm] )
+
+# xy and text both unitized
+ax.annotate('local max', xy=(3*cm, 1*cm), xycoords='data',
+ xytext=(0.8*cm, 0.95*cm), textcoords='data',
+ arrowprops=dict(facecolor='black', shrink=0.05),
+ horizontalalignment='right', verticalalignment='top')
+
+# mixing units w/ nonunits
+ax.annotate('local max', xy=(3*cm, 1*cm), xycoords='data',
+ xytext=(0.8, 0.95), textcoords='axes fraction',
+ arrowprops=dict(facecolor='black', shrink=0.05),
+ horizontalalignment='right', verticalalignment='top')
+
+
+ax.set_xlim(0*cm, 4*cm)
+ax.set_ylim(0*cm, 4*cm)
+pylab.show()
+
Copied: branches/transforms/examples/units/ellipse_with_units.py (from rev
3954, trunk/matplotlib/examples/units/ellipse_with_units.py)
===================================================================
--- branches/transforms/examples/units/ellipse_with_units.py
(rev 0)
+++ branches/transforms/examples/units/ellipse_with_units.py 2007-10-16
14:35:12 UTC (rev 3956)
@@ -0,0 +1,49 @@
+"""
+Compare the ellipse generated with arcs versus a polygonal approximation
+"""
+from basic_units import cm
+import numpy as npy
+from matplotlib import patches
+from pylab import figure, show
+
+xcenter, ycenter = 0.38*cm, 0.52*cm
+#xcenter, ycenter = 0., 0.
+width, height = 1e-1*cm, 3e-1*cm
+angle = -30
+
+theta = npy.arange(0.0, 360.0, 1.0)*npy.pi/180.0
+x = 0.5 * width * npy.cos(theta)
+y = 0.5 * height * npy.sin(theta)
+
+rtheta = angle*npy.pi/180.
+R = npy.array([
+ [npy.cos(rtheta), -npy.sin(rtheta)],
+ [npy.sin(rtheta), npy.cos(rtheta)],
+ ])
+
+
+x, y = npy.dot(R, npy.array([x, y]))
+x += xcenter
+y += ycenter
+
+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.Ellipse((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.Ellipse((xcenter, ycenter), width, height,
+ angle=angle, linewidth=2, fill=False, zorder=2)
+
+
+ax.add_patch(e2)
+
+#fig.savefig('ellipse_compare.png')
+fig.savefig('ellipse_compare')
+
+show()
Modified: branches/transforms/lib/matplotlib/backends/backend_ps.py
===================================================================
--- branches/transforms/lib/matplotlib/backends/backend_ps.py 2007-10-16
14:17:53 UTC (rev 3955)
+++ branches/transforms/lib/matplotlib/backends/backend_ps.py 2007-10-16
14:35:12 UTC (rev 3956)
@@ -331,7 +331,7 @@
size = prop.get_size_in_points()
font.set_size(size, 72.0)
return font
-
+
def _rgba(self, im):
return im.as_rgba_str()
@@ -398,7 +398,7 @@
#print 'values', origin, flipud, figh, h, y
if bbox is not None:
- clipx,clipy,clipw,cliph = bbox.get_bounds()
+ clipx,clipy,clipw,cliph = bbox.bounds
clip = '%s clipbox' % _nums_to_str(clipw, cliph, clipx, clipy)
#y = figh-(y+h)
ps = """gsave
@@ -1425,5 +1425,15 @@
box
clip
newpath
- } bind def"""
+ } bind def""",
+ """/unitcircle {
+ newpath
+-1. 0. moveto
+-1.0 0.552284749831 -0.552284749831 1.0 0.0 1.0 curveto
+0.552284749831 1.0 1.0 0.552284749831 1.0 0.0 curveto
+1.0 -0.552284749831 0.552284749831 -1.0 0.0 -1.0 curveto
+-0.552284749831 -1.0 -1.0 -0.552284749831 -1.0 0.0 curveto
+closepath
+ } bind def""",
+
]
Modified: branches/transforms/lib/matplotlib/cbook.py
===================================================================
--- branches/transforms/lib/matplotlib/cbook.py 2007-10-16 14:17:53 UTC (rev
3955)
+++ branches/transforms/lib/matplotlib/cbook.py 2007-10-16 14:35:12 UTC (rev
3956)
@@ -232,17 +232,18 @@
except TypeError: return False
else: return True
-def to_filehandle(fname):
+def to_filehandle(fname, flag='r'):
"""
fname can be a filename or a file handle. Support for gzipped
- files is automatic, if the filename ends in .gz
+ files is automatic, if the filename ends in .gz. flag is a
+ read/write flag for file
"""
if is_string_like(fname):
if fname.endswith('.gz'):
import gzip
- fh = gzip.open(fname)
+ fh = gzip.open(fname, flag)
else:
- fh = file(fname)
+ fh = file(fname, flag)
elif hasattr(fname, 'seek'):
fh = fname
else:
Modified: branches/transforms/lib/matplotlib/mlab.py
===================================================================
--- branches/transforms/lib/matplotlib/mlab.py 2007-10-16 14:17:53 UTC (rev
3955)
+++ branches/transforms/lib/matplotlib/mlab.py 2007-10-16 14:35:12 UTC (rev
3956)
@@ -809,6 +809,8 @@
If p is a scalar, the largest value of x less than or equal
to the p percentage point in the sequence is returned.
"""
+
+
x = npy.ravel(x)
x.sort()
Nx = len(x)
@@ -1282,7 +1284,10 @@
converterd, if not None, is a dictionary mapping column number or
munged column name to a converter function
- See examples/loadrec.py
+ 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 converterd is None:
@@ -1291,9 +1296,42 @@
import dateutil.parser
parsedate = dateutil.parser.parse
+
fh = cbook.to_filehandle(fname)
- reader = csv.reader(fh, delimiter=delimiter)
+
+ class FH:
+ """
+ for space delimited files, we want different behavior than
+ comma or tab. Generally, we want multiple spaces to be
+ treated as a single separator, whereas with comma and tab we
+ want multiple commas to return multiple (empty) fields. The
+ join/strip trick below effects this
+ """
+ def __init__(self, fh):
+ self.fh = fh
+
+ def close(self):
+ self.fh.close()
+
+ def seek(self, arg):
+ self.fh.seek(arg)
+
+ def fix(self, s):
+ return ' '.join(s.split())
+
+
+ def next(self):
+ return self.fix(self.fh.next())
+
+ def __iter__(self):
+ for line in self.fh:
+ yield self.fix(line)
+
+ if delimiter==' ':
+ fh = FH(fh)
+
+ reader = csv.reader(fh, delimiter=delimiter)
def process_skiprows(reader):
if skiprows:
for i, row in enumerate(reader):
@@ -1388,9 +1426,131 @@
rows.append([func(val) for func, val in zip(converters, row)])
fh.close()
+ if not len(rows):
+ return None
r = npy.rec.fromrecords(rows, names=names)
return r
+
+def rec2csv(r, fname, delimiter=','):
+ """
+ Save the data from numpy record array r into a comma/space/tab
+ delimited file. The record array dtype names will be used for
+ column headers.
+
+
+ fname - can be a filename or a file handle. Support for gzipped
+ files is automatic, if the filename ends in .gz
+ """
+ fh = cbook.to_filehandle(fname, 'w')
+ writer = csv.writer(fh, delimiter=delimiter)
+ header = r.dtype.names
+ writer.writerow(header)
+ for row in r:
+ writer.writerow(map(str, row))
+ fh.close()
+
+# some record array helpers
+def rec_append_field(rec, name, arr, dtype=None):
+ 'return a new record array with field name populated with data from array
arr'
+ arr = npy.asarray(arr)
+ if dtype is None:
+ dtype = arr.dtype
+ newdtype = npy.dtype(rec.dtype.descr + [(name, dtype)])
+ newrec = npy.empty(rec.shape, dtype=newdtype)
+ for field in rec.dtype.fields:
+ newrec[field] = rec[field]
+ newrec[name] = arr
+ return newrec.view(npy.recarray)
+
+
+def rec_drop_fields(rec, names):
+ 'return a new numpy record array with fields in names dropped'
+
+ names = set(names)
+ Nr = len(rec)
+
+ newdtype = npy.dtype([(name, rec.dtype[name]) for name in rec.dtype.names
+ if name not in names])
+
+ newrec = npy.empty(Nr, dtype=newdtype)
+ for field in newdtype.names:
+ newrec[field] = rec[field]
+
+ return newrec.view(npy.recarray)
+
+
+def rec_join(key, r1, r2):
+ """
+ join record arrays r1 and r2 on key; key is a tuple of field
+ names. if r1 and r2 have equal values on all the keys in the key
+ tuple, then their fields will be merged into a new record array
+ containing the union of the fields of r1 and r2
+ """
+
+ for name in key:
+ if name not in r1.dtype.names:
+ raise ValueError('r1 does not have key field %s'%name)
+ if name not in r2.dtype.names:
+ raise ValueError('r2 does not have key field %s'%name)
+
+ def makekey(row):
+ return tuple([row[name] for name in key])
+
+
+ names = list(r1.dtype.names) + [name for name in r2.dtype.names if name
not in set(r1.dtype.names)]
+
+
+
+ r1d = dict([(makekey(row),i) for i,row in enumerate(r1)])
+ r2d = dict([(makekey(row),i) for i,row in enumerate(r2)])
+
+ r1keys = set(r1d.keys())
+ r2keys = set(r2d.keys())
+
+ keys = r1keys & r2keys
+
+ r1ind = [r1d[k] for k in keys]
+ r2ind = [r2d[k] for k in keys]
+
+
+ r1 = r1[r1ind]
+ r2 = r2[r2ind]
+
+ r2 = rec_drop_fields(r2, r1.dtype.names)
+
+
+ def key_desc(name):
+ 'if name is a string key, use the larger size of r1 or r2 before
merging'
+ dt1 = r1.dtype[name]
+ if dt1.type != npy.string_:
+ return (name, dt1.descr[0][1])
+
+ dt2 = r1.dtype[name]
+ assert dt2==dt1
+ if dt1.num>dt2.num:
+ return (name, dt1.descr[0][1])
+ else:
+ return (name, dt2.descr[0][1])
+
+
+
+ keydesc = [key_desc(name) for name in key]
+
+ newdtype = npy.dtype(keydesc +
+ [desc for desc in r1.dtype.descr if desc[0] not in
key ] +
+ [desc for desc in r2.dtype.descr if desc[0] not in
key ] )
+
+
+ newrec = npy.empty(len(r1), dtype=newdtype)
+ for field in r1.dtype.names:
+ newrec[field] = r1[field]
+
+ for field in r2.dtype.names:
+ newrec[field] = r2[field]
+
+ return newrec.view(npy.recarray)
+
def slopes(x,y):
"""
SLOPES calculate the slope y'(x) Given data vectors X and Y SLOPES
Modified: branches/transforms/lib/matplotlib/patches.py
===================================================================
--- branches/transforms/lib/matplotlib/patches.py 2007-10-16 14:17:53 UTC
(rev 3955)
+++ branches/transforms/lib/matplotlib/patches.py 2007-10-16 14:35:12 UTC
(rev 3956)
@@ -771,6 +771,32 @@
"""
A scale-free ellipse
"""
+ offset = 4.0 * (npy.sqrt(2) - 1) / 3.0
+
+ circle = 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],
+
+ [-1.0, 0.0]
+ ],
+ npy.float_)
+
+
def __str__(self):
return
"Ellipse(%d,%d;%dx%d)"%(self.center[0],self.center[1],self.width,self.height)
@@ -807,8 +833,8 @@
if ev.x is None or ev.y is None: return False,{}
x, y = self.get_transform().inverted().transform_point((ev.x, ev.y))
return (x*x + y*y) <= 1.0, {}
+
-
class Circle(Ellipse):
"""
A circle patch
Modified: branches/transforms/lib/matplotlib/text.py
===================================================================
--- branches/transforms/lib/matplotlib/text.py 2007-10-16 14:17:53 UTC (rev
3955)
+++ branches/transforms/lib/matplotlib/text.py 2007-10-16 14:35:12 UTC (rev
3956)
@@ -1041,6 +1041,8 @@
def _get_xy(self, x, y, s):
if s=='data':
trans = self.axes.transData
+ x = float(self.convert_xunits(x))
+ y = float(self.convert_yunits(y))
return trans.transform_point((x, y))
elif s=='polar':
theta, r = x, y
Modified: branches/transforms/src/_backend_agg.cpp
===================================================================
--- branches/transforms/src/_backend_agg.cpp 2007-10-16 14:17:53 UTC (rev
3955)
+++ branches/transforms/src/_backend_agg.cpp 2007-10-16 14:35:12 UTC (rev
3956)
@@ -653,7 +653,6 @@
}
-
/**
* This is a custom span generator that converts spans in the
* 8-bit inverted greyscale font buffer to rgba that agg can use.
@@ -776,11 +775,16 @@
srcbuf, 0, interpolator, filter);
span_gen_type output_span_generator(&image_span_generator, gc.color);
renderer_type ri(*rendererBase, output_span_generator);
- agg::rasterizer_scanline_aa<> rasterizer;
- agg::scanline_p8 scanline;
- rasterizer.add_path(rect2);
- agg::render_scanlines(rasterizer, scanline, ri);
+ //agg::rasterizer_scanline_aa<> rasterizer;
+ //agg::scanline_p8 scanline;
+ //rasterizer.add_path(rect2);
+ //agg::render_scanlines(rasterizer, scanline, ri);
+
+ theRasterizer->add_path(rect2);
+ agg::render_scanlines(*theRasterizer, *slineP8, ri);
+
+
return Py::Object();
}
Modified: branches/transforms/ttconv/ttutil.cpp
===================================================================
--- branches/transforms/ttconv/ttutil.cpp 2007-10-16 14:17:53 UTC (rev
3955)
+++ branches/transforms/ttconv/ttutil.cpp 2007-10-16 14:35:12 UTC (rev
3956)
@@ -32,14 +32,14 @@
va_start(arg_list, format);
char buffer[PRINTF_BUFFER_SIZE];
-#ifdef WIN32
+#if defined(WIN32) || defined(_MSC_VER)
int size = _vsnprintf(buffer, PRINTF_BUFFER_SIZE, format, arg_list);
#else
int size = vsnprintf(buffer, PRINTF_BUFFER_SIZE, format, arg_list);
#endif
if (size >= PRINTF_BUFFER_SIZE) {
char* buffer2 = (char*)malloc(size);
-#ifdef WIN32
+#if defined(WIN32) || defined(_MSC_VER)
_vsnprintf(buffer2, size, format, arg_list);
#else
vsnprintf(buffer2, size, format, arg_list);
Modified: branches/transforms/unit/ellipse_compare.py
===================================================================
--- branches/transforms/unit/ellipse_compare.py 2007-10-16 14:17:53 UTC (rev
3955)
+++ branches/transforms/unit/ellipse_compare.py 2007-10-16 14:35:12 UTC (rev
3956)
@@ -27,27 +27,22 @@
fig = figure()
ax = fig.add_subplot(211, aspect='auto')
-ax.fill(x, y, alpha=0.2, facecolor='yellow')
+ax.fill(x, y, alpha=0.2, facecolor='yellow', edgecolor='yellow', linewidth=1,
zorder=1)
e1 = patches.Ellipse((xcenter, ycenter), width, height,
- angle=angle, linewidth=2, fill=False)
+ angle=angle, linewidth=2, fill=False, zorder=2)
-ax.add_artist(e1)
+ax.add_patch(e1)
ax = fig.add_subplot(212, aspect='equal')
-ax.fill(x, y, alpha=0.2, facecolor='yellow')
+ax.fill(x, y, alpha=0.2, facecolor='green', edgecolor='green', zorder=1)
e2 = patches.Ellipse((xcenter, ycenter), width, height,
- angle=angle, linewidth=2, fill=False)
+ angle=angle, linewidth=2, fill=False, zorder=2)
-ax.add_artist(e2)
-ax.autoscale_view()
+ax.add_patch(e2)
-
-ax.set_xlim(0.2, .5)
-ax.set_ylim(0.3, 0.7)
-
#fig.savefig('ellipse_compare.png')
-#fig.savefig('ellipse_compare.ps')
+fig.savefig('ellipse_compare')
show()
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: Splunk Inc.
Still grepping through log files to find problems? Stop.
Now Search log events and configuration files using AJAX and a browser.
Download your FREE copy of Splunk now >> http://get.splunk.com/
_______________________________________________
Matplotlib-checkins mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/matplotlib-checkins