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
Matplotlib-checkins@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/matplotlib-checkins

Reply via email to