Revision: 4004
          http://matplotlib.svn.sourceforge.net/matplotlib/?rev=4004&view=rev
Author:   mdboom
Date:     2007-10-25 12:16:11 -0700 (Thu, 25 Oct 2007)

Log Message:
-----------
Increased coverage of backend_driver.py to include almost everything
in axes.py.  Lots of little bug fixes.

Modified Paths:
--------------
    branches/transforms/PASSED_DEMOS
    branches/transforms/examples/arrow_demo.py
    branches/transforms/examples/backend_driver.py
    branches/transforms/lib/matplotlib/artist.py
    branches/transforms/lib/matplotlib/axes.py
    branches/transforms/lib/matplotlib/backend_bases.py
    branches/transforms/lib/matplotlib/backends/backend_pdf.py
    branches/transforms/lib/matplotlib/backends/backend_ps.py
    branches/transforms/lib/matplotlib/backends/backend_svg.py
    branches/transforms/lib/matplotlib/backends/backend_template.py
    branches/transforms/lib/matplotlib/cbook.py
    branches/transforms/lib/matplotlib/collections.py
    branches/transforms/lib/matplotlib/contour.py
    branches/transforms/lib/matplotlib/lines.py
    branches/transforms/lib/matplotlib/patches.py
    branches/transforms/lib/matplotlib/path.py
    branches/transforms/lib/matplotlib/scale.py
    branches/transforms/lib/matplotlib/transforms.py
    branches/transforms/lib/matplotlib/widgets.py
    branches/transforms/src/_gtkagg.cpp

Added Paths:
-----------
    branches/transforms/examples/equal_aspect_ratio.py
    branches/transforms/examples/hline_demo.py

Modified: branches/transforms/PASSED_DEMOS
===================================================================
--- branches/transforms/PASSED_DEMOS    2007-10-25 18:16:03 UTC (rev 4003)
+++ branches/transforms/PASSED_DEMOS    2007-10-25 19:16:11 UTC (rev 4004)
@@ -60,7 +60,7 @@
 dynamic_demo_wx.py     [REQUIRES NON-AGG WX RENDERER, WHICH IS NOT YET 
IMPLEMENTED]
 dynamic_image_gtkagg.py O
 dynamic_image_wxagg2.py O
-dynamic_image_wxagg.py 
+dynamic_image_wxagg.py [REQUIRES NON-AGG WX RENDERER, WHICH IS NOT YET 
IMPLEMENTED]
 ellipse_demo.py                O
 ellipse_rotated.py     O
 embedding_in_gtk2.py   [REQUIRES NON-AGG GDK RENDERER, WHICH IS NOT YET 
IMPLEMENTED]

Modified: branches/transforms/examples/arrow_demo.py
===================================================================
--- branches/transforms/examples/arrow_demo.py  2007-10-25 18:16:03 UTC (rev 
4003)
+++ branches/transforms/examples/arrow_demo.py  2007-10-25 19:16:11 UTC (rev 
4004)
@@ -280,6 +280,7 @@
 
 if __name__ == '__main__':
     from sys import argv
+    d = None
     if len(argv) > 1:
         if argv[1] == 'full':
             d = all_on_max
@@ -293,7 +294,7 @@
         elif argv[1] == 'sample':
             d = sample_data
             scaled = True
-    else:
+    if d is None:
         d = all_on_max
         scaled=False
     if len(argv) > 2:

Modified: branches/transforms/examples/backend_driver.py
===================================================================
--- branches/transforms/examples/backend_driver.py      2007-10-25 18:16:03 UTC 
(rev 4003)
+++ branches/transforms/examples/backend_driver.py      2007-10-25 19:16:11 UTC 
(rev 4004)
@@ -22,10 +22,16 @@
 files = (
     'alignment_test.py',
     'arctest.py',
+    'arrow_demo.py',
     'axes_demo.py',
+    'axhspan_demo.py',
     'bar_stacked.py',
     'barchart_demo.py',
+    'boxplot_demo.py',
+    'broken_barh.py',
+    'barh_demo.py',
     'color_demo.py',
+    'colorbar_only.py',
     'contour_demo.py',
     'contourf_demo.py',
     'csd_demo.py',
@@ -33,6 +39,8 @@
     'customize_rc.py',
     'date_demo1.py',
     'date_demo2.py',
+    'equal_aspect_ratio.py',
+    'errorbar_limits.py',
     'figimage_demo.py',
     'figlegend_demo.py',
     'figtext.py',
@@ -40,6 +48,7 @@
     'finance_demo.py',
     'fonts_demo_kw.py',
     'histogram_demo.py',
+    'hline_demo.py',
     'image_demo.py',
     'image_demo2.py',
     'image_masked.py',
@@ -66,11 +75,18 @@
     'polar_demo.py',
     'polar_scatter.py',
     'psd_demo.py',
+    'quadmesh_demo.py',
     'quiver_demo.py',
     'scatter_demo.py',
     'scatter_demo2.py',
+    'scatter_star_poly.py',
+    'shared_axis_demo.py',
+    'shared_axis_across_figures.py',
     'simple_plot.py',
     'specgram_demo.py',
+    'spy_demos.py',
+    'stem_plot.py',
+    'step_demo.py',
     'stock_demo.py',
     'subplot_demo.py',
 #    'set_and_get.py',
@@ -104,7 +120,7 @@
     def run(arglist):
         os.system(' '.join(arglist))
 
-def drive(backend, python='python', switches = []):
+def drive(backend, python=['python'], switches = []):
 
     exclude = failbackend.get(backend, [])
     switchstring = ' '.join(switches)
@@ -151,17 +167,20 @@
             tmpfile.write('savefig("%s", dpi=150)' % outfile)
 
         tmpfile.close()
-        run([python, tmpfile_name, switchstring])
+        run(python + [tmpfile_name, switchstring])
         #os.system('%s %s %s' % (python, tmpfile_name, switchstring))
         os.remove(tmpfile_name)
 
 if __name__ == '__main__':
     times = {}
     default_backends = ['Agg', 'PS', 'SVG', 'PDF', 'Template']
-    if sys.platform == 'win32':
-        python = r'c:\Python24\python.exe'
+    if '--coverage' in sys.argv:
+        python = ['coverage.py', '-x']
+        sys.argv.remove('--coverage')
+    elif sys.platform == 'win32':
+        python = [r'c:\Python24\python.exe']
     else:
-        python = 'python'
+        python = ['python']
     all_backends = [b.lower() for b in mplbe.all_backends]
     all_backends.extend(['cairo.png', 'cairo.ps', 'cairo.pdf', 'cairo.svg'])
     backends = []

Added: branches/transforms/examples/equal_aspect_ratio.py
===================================================================
--- branches/transforms/examples/equal_aspect_ratio.py                          
(rev 0)
+++ branches/transforms/examples/equal_aspect_ratio.py  2007-10-25 19:16:11 UTC 
(rev 4004)
@@ -0,0 +1,23 @@
+#!/usr/bin/env python
+"""
+Example: simple line plot.
+Show how to make a plot that has equal aspect ratio
+"""
+from pylab import *
+
+t = arange(0.0, 1.0+0.01, 0.01)
+s = cos(2*2*pi*t)
+plot(t, s, '-', lw=2)
+
+xlabel('time (s)')
+ylabel('voltage (mV)')
+title('About as simple as it gets, folks')
+grid(True)
+
+axes().set_aspect('equal', 'datalim')
+
+
+#savefig('simple_plot.png')
+savefig('equal_aspect')
+
+show()


Property changes on: branches/transforms/examples/equal_aspect_ratio.py
___________________________________________________________________
Name: svn:executable
   + *

Added: branches/transforms/examples/hline_demo.py
===================================================================
--- branches/transforms/examples/hline_demo.py                          (rev 0)
+++ branches/transforms/examples/hline_demo.py  2007-10-25 19:16:11 UTC (rev 
4004)
@@ -0,0 +1,21 @@
+#!/usr/bin/env python
+from matplotlib.pyplot import *
+from numpy import sin, exp,  absolute, pi, arange
+from numpy.random import normal
+
+def f(t):
+    s1 = sin(2*pi*t)
+    e1 = exp(-t)
+    return absolute((s1*e1))+.05
+
+
+t = arange(0.0, 5.0, 0.1)
+s = f(t)
+nse = normal(0.0, 0.3, t.shape) * s
+
+plot(s+nse, t, 'b^')
+hlines(t, [0], s)
+xlabel('time (s)')
+title('Comparison of model with data')
+show()
+


Property changes on: branches/transforms/examples/hline_demo.py
___________________________________________________________________
Name: svn:executable
   + *

Modified: branches/transforms/lib/matplotlib/artist.py
===================================================================
--- branches/transforms/lib/matplotlib/artist.py        2007-10-25 18:16:03 UTC 
(rev 4003)
+++ branches/transforms/lib/matplotlib/artist.py        2007-10-25 19:16:11 UTC 
(rev 4004)
@@ -1,5 +1,5 @@
 from __future__ import division
-import sys, re
+import sys, re, warnings
 from cbook import iterable, flatten
 from transforms import Affine2D, Bbox, IdentityTransform, TransformedBbox, \
     TransformedPath
@@ -174,7 +174,7 @@
         """
         if callable(self._contains): return self._contains(self,mouseevent)
         #raise NotImplementedError,str(self.__class__)+" needs 'contains' 
method"
-        print str(self.__class__)+" needs 'contains' method"
+        warnings.warn("'%s' needs 'contains' method" % self.__class__.__name__)
         return False,{}
 
     def set_contains(self,picker):

Modified: branches/transforms/lib/matplotlib/axes.py
===================================================================
--- branches/transforms/lib/matplotlib/axes.py  2007-10-25 18:16:03 UTC (rev 
4003)
+++ branches/transforms/lib/matplotlib/axes.py  2007-10-25 19:16:11 UTC (rev 
4004)
@@ -821,16 +821,15 @@
         Use self._aspect and self._adjustable to modify the
         axes box or the view limits.
         '''
-        #MGDTODO: Numpify
-
-        if self._aspect == 'auto':
+        aspect = self.get_aspect()
+        if aspect == 'auto':
             self.set_position( self._originalPosition , 'active')
             return
 
-        if self._aspect == 'equal':
+        if aspect == 'equal':
             A = 1
         else:
-            A = self._aspect
+            A = aspect
 
         #Ensure at drawing time that any Axes involved in axis-sharing
         # does not have its position changed.
@@ -843,7 +842,7 @@
             box_aspect = A * self.get_data_ratio()
             pb = self._originalPosition.frozen()
             pb1 = pb.shrunk_to_aspect(box_aspect, pb, fig_aspect)
-            self.set_position(pb1.anchored(self._anchor, pb), 'active')
+            self.set_position(pb1.anchored(self.get_anchor(), pb), 'active')
             return
 
         xmin,xmax = self.get_xbound()
@@ -1040,7 +1039,7 @@
         a.set_clip_path(self.axesPatch)
         a._remove_method = lambda h: self.artists.remove(h)
 
-    def add_collection(self, collection, autolim=False):
+    def add_collection(self, collection, autolim=True):
         'add a Collection instance to Axes'
         label = collection.get_label()
         if not label:
@@ -1127,8 +1126,8 @@
        self.ignore_existing_data_limits = False
 
     def update_datalim_bounds(self, bounds):
-        # MGDTODO: Document me
-        self.dataLim.bounds = Bbox.union([self.dataLim, bounds]).bounds
+        'Update the datalim to include the given Bbox'
+        self.dataLim.set(Bbox.union([self.dataLim, bounds]))
         
     def _get_verts_in_data_coords(self, trans, xys):
         if trans == self.transData:
@@ -2017,8 +2016,9 @@
         Note this algorithm calculates distance to the vertices of the
         polygon, so if you want to pick a patch, click on the edge!
         """
+        # MGDTODO: Needs updating
         if trans is not None:
-            xywin = trans.xy_tup((x,y))
+            xywin = trans.transform_point((x,y))
         else:
             xywin = x,y
 
@@ -2036,12 +2036,12 @@
         def dist(a):
             if isinstance(a, Text):
                 bbox = a.get_window_extent()
-                l,b,w,h = bbox.get_bounds()
+                l,b,w,h = bbox.bounds
                 verts = (l,b), (l,b+h), (l+w,b+h), (l+w, b)
                 xt, yt = zip(*verts)
             elif isinstance(a, Patch):
-                verts = a.get_verts()
-                tverts = a.get_transform().seq_xy_tups(verts)
+                path = a.get_path()
+                tverts = a.get_transform().transform_path(path)
                 xt, yt = zip(*tverts)
             elif isinstance(a, mlines.Line2D):
                 xdata = a.get_xdata(orig=False)
@@ -3278,19 +3278,19 @@
         self.hold(holdstate) # restore previous hold state
 
         if adjust_xlim:
-            xmin, xmax = self.dataLim.intervalx().get_bounds()
+            xmin, xmax = self.dataLim.intervalx
             xmin = npy.amin(width)
             if xerr is not None:
                 xmin = xmin - npy.amax(xerr)
             xmin = max(xmin*0.9, 1e-100)
-            self.dataLim.intervalx().set_bounds(xmin, xmax)
+            self.dataLim.intervalx = (xmin, xmax)
         if adjust_ylim:
-            ymin, ymax = self.dataLim.intervaly().get_bounds()
+            ymin, ymax = self.dataLim.intervaly
             ymin = npy.amin(height)
             if yerr is not None:
                 ymin = ymin - npy.amax(yerr)
             ymin = max(ymin*0.9, 1e-100)
-            self.dataLim.intervaly().set_bounds(ymin, ymax)
+            self.dataLim.intervaly = (ymin, ymax)
         self.autoscale_view()
         return patches
     bar.__doc__ = cbook.dedent(bar.__doc__) % martist.kwdocd
@@ -4197,7 +4197,7 @@
 
     def quiver(self, *args, **kw):
         q = mquiver.Quiver(self, *args, **kw)
-        self.add_collection(q)
+        self.add_collection(q, False)
         self.update_datalim_numerix(q.X, q.Y)
         self.autoscale_view()
         return q
@@ -5170,6 +5170,7 @@
         'get the subplot geometry, eg 2,2,3'
         return self._rows, self._cols, self._num+1
 
+    # COVERAGE NOTE: Never used internally or from examples
     def change_geometry(self, numrows, numcols, num):
         'change subplot geometry, eg from 1,1,1 to 2,2,3'
         self._rows = numrows
@@ -5238,6 +5239,7 @@
     def is_last_col(self):
         return self.colNum==self.numCols-1
 
+    # COVERAGE NOTE: Never used internally or from examples
     def label_outer(self):
         """
         set the visible property on ticklabels so xticklabels are

Modified: branches/transforms/lib/matplotlib/backend_bases.py
===================================================================
--- branches/transforms/lib/matplotlib/backend_bases.py 2007-10-25 18:16:03 UTC 
(rev 4003)
+++ branches/transforms/lib/matplotlib/backend_bases.py 2007-10-25 19:16:11 UTC 
(rev 4004)
@@ -223,7 +223,7 @@
         baseline (descent), in display coords of the string s with
         FontPropertry prop
         """
-        return 1,1,1
+        raise NotImplementedError
 
     def new_gc(self):
         """

Modified: branches/transforms/lib/matplotlib/backends/backend_pdf.py
===================================================================
--- branches/transforms/lib/matplotlib/backends/backend_pdf.py  2007-10-25 
18:16:03 UTC (rev 4003)
+++ branches/transforms/lib/matplotlib/backends/backend_pdf.py  2007-10-25 
19:16:11 UTC (rev 4004)
@@ -1180,11 +1180,12 @@
     def get_image_magnification(self):
         return self.image_magnification
 
-    def draw_image(self, x, y, im, bbox):
+    def draw_image(self, x, y, im, bbox, clippath=None, clippath_trans=None):
         #print >>sys.stderr, "draw_image called"
 
+        # MGDTODO: Support clippath here
         gc = self.new_gc()
-        gc.set_clip_rectangle(bbox.get_bounds())
+        gc.set_clip_rectangle(bbox.bounds)
         self.check_gc(gc)
 
         h, w = im.get_size_out()
@@ -1714,13 +1715,19 @@
         """
         cmds = []
         for params, cmd in self.commands:
-            ours = [ getattr(self, p) for p in params ] 
-            theirs = [ getattr(other, p) for p in params ]
-            try:
-                different = ours != theirs
-            except ValueError:
-                different = ours.shape != theirs.shape or npy.any(ours != 
theirs)
-            if ours is not theirs:
+            different = False
+            for p in params:
+                ours = getattr(self, p)
+                theirs = getattr(other, p)
+                try:
+                    different = bool(ours != theirs)
+                except ValueError:
+                    different = ours.shape != theirs.shape or npy.any(ours != 
theirs)
+                if different:
+                    break
+                
+            if different:
+                theirs = [getattr(other, p) for p in params]
                 cmds.extend(cmd(self, *theirs))
                 for p in params:
                     setattr(self, p, getattr(other, p))

Modified: branches/transforms/lib/matplotlib/backends/backend_ps.py
===================================================================
--- branches/transforms/lib/matplotlib/backends/backend_ps.py   2007-10-25 
18:16:03 UTC (rev 4003)
+++ branches/transforms/lib/matplotlib/backends/backend_ps.py   2007-10-25 
19:16:11 UTC (rev 4004)
@@ -994,12 +994,12 @@
         tmpfile = os.path.join(gettempdir(), md5.md5(outfile).hexdigest())
         fh = file(tmpfile, 'w')
 
-        self.figure.dpi.set(72) # ignore the dpi kwarg
+        self.figure.dpi = 72 # ignore the dpi kwarg
         width, height = self.figure.get_size_inches()
         xo = 0
         yo = 0
 
-        l, b, w, h = self.figure.bbox.get_bounds()
+        l, b, w, h = self.figure.bbox.bounds
         llx = xo
         lly = yo
         urx = llx + w

Modified: branches/transforms/lib/matplotlib/backends/backend_svg.py
===================================================================
--- branches/transforms/lib/matplotlib/backends/backend_svg.py  2007-10-25 
18:16:03 UTC (rev 4003)
+++ branches/transforms/lib/matplotlib/backends/backend_svg.py  2007-10-25 
19:16:11 UTC (rev 4004)
@@ -193,7 +193,8 @@
             details = 'xlink:href="#%s" x="%f" y="%f"' % (name, x, y)
             self._draw_svg_element('use', details, gc, rgbFace)
             
-    def draw_image(self, x, y, im, bbox):
+    def draw_image(self, x, y, im, bbox, clippath=None, clippath_trans=None):
+        # MGDTODO: Support clippath here
         trans = [1,0,0,1,0,0]
         transstr = ''
         if rcParams['svg.image_noscale']:

Modified: branches/transforms/lib/matplotlib/backends/backend_template.py
===================================================================
--- branches/transforms/lib/matplotlib/backends/backend_template.py     
2007-10-25 18:16:03 UTC (rev 4003)
+++ branches/transforms/lib/matplotlib/backends/backend_template.py     
2007-10-25 19:16:11 UTC (rev 4004)
@@ -66,24 +66,23 @@
                  rotation):
         pass
 
-    def draw_image(self, x, y, im, bbox):
+    def draw_path(self, gc, path, transform, rgbFace=None):
         pass
 
-    def draw_line(self, gc, x1, y1, x2, y2):
+    def draw_markers(self, gc, marker_path, marker_trans, path, trans, 
rgbFace=None):
         pass
 
-    def draw_lines(self, gc, x, y):
+    # draw_path_collection is optional, and we get more correct
+    # relative timings by leaving it out.
+#     def draw_path_collection(self, master_transform, cliprect, clippath,
+#                              clippath_trans, paths, all_transforms, offsets,
+#                              offsetTrans, facecolors, edgecolors, linewidths,
+#                              linestyles, antialiaseds):
+#         pass
+    
+    def draw_image(self, x, y, im, bbox, clippath=None, clippath_trans=None):
         pass
 
-    def draw_point(self, gc, x, y):
-        pass
-
-    def draw_polygon(self, gcEdge, rgbFace, points):
-        pass
-
-    def draw_rectangle(self, gcEdge, rgbFace, x, y, width, height):
-        pass
-
     def draw_text(self, gc, x, y, s, prop, angle, ismath=False):
         pass
 

Modified: branches/transforms/lib/matplotlib/cbook.py
===================================================================
--- branches/transforms/lib/matplotlib/cbook.py 2007-10-25 18:16:03 UTC (rev 
4003)
+++ branches/transforms/lib/matplotlib/cbook.py 2007-10-25 19:16:11 UTC (rev 
4004)
@@ -174,7 +174,6 @@
     def __str__(self):
         return '<a list of %d %s objects>' % (len(self), self.type)
 
-# MGDTODO: This is very incomplete
 def strip_math(s):
     'remove latex formatting from mathtext'
     remove = (r'\rm', '\cal', '\tt', '\it', '\\', '{', '}')

Modified: branches/transforms/lib/matplotlib/collections.py
===================================================================
--- branches/transforms/lib/matplotlib/collections.py   2007-10-25 18:16:03 UTC 
(rev 4003)
+++ branches/transforms/lib/matplotlib/collections.py   2007-10-25 19:16:11 UTC 
(rev 4004)
@@ -126,13 +126,21 @@
         return self._transforms
         
     def get_datalim(self, transData):
+        transform = self.get_transform()
+        transOffset = self._transOffset
+        offsets = self._offsets
+        paths = self.get_paths()
+        if not transform.is_affine:
+            paths = [transform.transform_path_non_affine(p) for p in paths]
+            transform = transform.get_affine()
+        if not transOffset.is_affine:
+            offsets = transOffset.transform_non_affine(offsets)
+            transOffset = transOffset.get_affine()
+        
         result = path.get_path_collection_extents(
-            self.get_transform().frozen(),
-            self.get_paths(),
-            self.get_transforms(),
-            self._offsets,
-            self._transOffset.frozen())
-        result = result.transformed(transData.inverted())
+            transform.frozen(), paths, self.get_transforms(),
+            npy.asarray(offsets, npy.float_), transOffset.frozen())
+        result = result.inverse_transformed(transData)
         return result
 
     def draw(self, renderer):
@@ -143,7 +151,6 @@
         offsets = self._offsets
         paths = self.get_paths()
 
-        # MGDTODO: Test me
         if self.have_units():
             paths = []
             for path in self._paths:
@@ -163,7 +170,6 @@
         if clippath_trans is not None:
             clippath_trans = clippath_trans.frozen()
         
-        # MGDTODO: This may benefit from using TransformedPath
         if not transform.is_affine:
             paths = [transform.transform_path_non_affine(path) for path in 
paths]
             transform = transform.get_affine()
@@ -193,7 +199,6 @@
             paths = [transform.transform_path_non_affine(path) for path in 
paths]
             transform = transform.get_affine()
 
-        # MGDTODO: Don't pick when outside of clip path / clip box
         ind = path.point_in_path_collection(
             mouseevent.x, mouseevent.y, self._pickradius,
             transform.frozen(), paths, self.get_transforms(),
@@ -201,45 +206,6 @@
             self._transOffset.frozen(), len(self._facecolors))
         return len(ind)>0,dict(ind=ind)
 
-    # MGDTODO: Update
-    def get_transformed_patches(self):
-        """
-        get a sequence of the polygons in the collection in display 
(transformed) space
-
-        The ith element in the returned sequence is a list of x,y
-        vertices defining the ith polygon
-        """
-
-        verts = self._verts
-        offsets = self._offsets
-        usingOffsets = offsets is not None
-        transform = self.get_transform()
-        transOffset = self.get_transoffset()
-        Noffsets = 0
-        Nverts = len(verts)
-        if usingOffsets:
-            Noffsets = len(offsets)
-
-        N = max(Noffsets, Nverts)
-
-        data = []
-        #print 'verts N=%d, Nverts=%d'%(N, Nverts), verts
-        #print 'offsets; Noffsets=%d'%Noffsets
-        for i in xrange(N):
-            #print 'i%%Nverts=%d'%(i%Nverts)
-            polyverts = verts[i % Nverts]
-            if npy.any(npy.isnan(polyverts)):
-                continue
-            #print 'thisvert', i, polyverts
-            tverts = transform.seq_xy_tups(polyverts)
-            if usingOffsets:
-                #print 'using offsets'
-                xo,yo = transOffset.xy_tup(offsets[i % Noffsets])
-                tverts = [(x+xo,y+yo) for x,y in tverts]
-
-            data.append(tverts)
-        return data
-
     def set_pickradius(self,pickradius): self.pickradius = 5
     def get_pickradius(self): return self.pickradius
     
@@ -414,8 +380,8 @@
         self._meshHeight = meshHeight
         self._coordinates = coordinates
         self._showedges = showedges
-            
-        # MGDTODO: Numpify
+
+        # MGDTODO: Is it possible to Numpify this?
         coordinates = coordinates.reshape((meshHeight + 1, meshWidth + 1, 2))
         c = coordinates
         paths = []
@@ -542,24 +508,6 @@
 
     def get_paths(self):
         return self._paths
-    
-    # MGDTODO: Update
-    def get_transformed_patches(self):
-        # Shouldn't need all these calls to asarray;
-        # the variables should be converted when stored.
-        # Similar speedups with numpy should be attainable
-        # in many other places.
-        verts = npy.asarray(self._verts)
-        offsets = npy.asarray(self._offsets)
-        Npoly = len(offsets)
-        scales = npy.sqrt(npy.asarray(self._sizes)*self._dpi.get()/72.0)
-        Nscales = len(scales)
-        if Nscales >1:
-            scales = npy.resize(scales, (Npoly, 1, 1))
-        transOffset = self.get_transoffset()
-        xyo = transOffset.numerix_xy(offsets)
-        polys = scales * verts + xyo[:, npy.newaxis, :]
-        return polys
 
 
 class StarPolygonCollection(RegularPolyCollection):

Modified: branches/transforms/lib/matplotlib/contour.py
===================================================================
--- branches/transforms/lib/matplotlib/contour.py       2007-10-25 18:16:03 UTC 
(rev 4003)
+++ branches/transforms/lib/matplotlib/contour.py       2007-10-25 19:16:11 UTC 
(rev 4004)
@@ -464,7 +464,7 @@
                     ls = mpl.rcParams['contour.negative_linestyle']
                     col.set_linestyle(ls)
                 col.set_label('_nolegend_')
-                self.ax.add_collection(col)
+                self.ax.add_collection(col, False)
                 self.collections.append(col)
         self.changed() # set the colors
         x0 = ma.minimum(x)

Modified: branches/transforms/lib/matplotlib/lines.py
===================================================================
--- branches/transforms/lib/matplotlib/lines.py 2007-10-25 18:16:03 UTC (rev 
4003)
+++ branches/transforms/lib/matplotlib/lines.py 2007-10-25 19:16:11 UTC (rev 
4004)
@@ -25,6 +25,7 @@
 (TICKLEFT, TICKRIGHT, TICKUP, TICKDOWN,
     CARETLEFT, CARETRIGHT, CARETUP, CARETDOWN) = range(8)
 
+# COVERAGE NOTE: Never called internally or from examples
 def unmasked_index_ranges(mask, compressed = True):
     '''
     Calculate the good data ranges in a masked 1-D npy.array, based on mask.
@@ -72,45 +73,6 @@
     ic1 = breakpoints
     return npy.concatenate((ic0[:, npy.newaxis], ic1[:, npy.newaxis]), axis=1)
 
-def segment_hits(cx,cy,x,y,radius):
-    """Determine if any line segments are within radius of a point. Returns
-    the list of line segments that are within that radius.
-    """
-    # Process single points specially
-    if len(x) < 2:
-        res, = npy.nonzero( (cx - x)**2 + (cy - y)**2 <= radius**2 )
-        return res
-
-    # We need to lop the last element off a lot.
-    xr,yr = x[:-1],y[:-1]
-
-    # Only look at line segments whose nearest point to C on the line
-    # lies within the segment.
-    dx,dy = x[1:]-xr, y[1:]-yr
-    Lnorm_sq = dx**2+dy**2    # Possibly want to eliminate Lnorm==0
-    u = ( (cx-xr)*dx + (cy-yr)*dy )/Lnorm_sq
-    candidates = (u>=0) & (u<=1)
-    #if any(candidates): print "candidates",xr[candidates]
-
-    # Note that there is a little area near one side of each point
-    # which will be near neither segment, and another which will
-    # be near both, depending on the angle of the lines.  The
-    # following radius test eliminates these ambiguities.
-    point_hits = (cx - x)**2 + (cy - y)**2 <= radius**2
-    #if any(point_hits): print "points",xr[candidates]
-    candidates = candidates & ~point_hits[:-1] & ~point_hits[1:]
-
-    # For those candidates which remain, determine how far they lie away
-    # from the line.
-    px,py = xr+u*dx,yr+u*dy
-    line_hits = (cx-px)**2 + (cy-py)**2 <= radius**2
-    #if any(line_hits): print "lines",xr[candidates]
-    line_hits = line_hits & candidates
-    points, = point_hits.ravel().nonzero()
-    lines, = line_hits.ravel().nonzero()
-    #print points,lines
-    return npy.concatenate((points,lines))
-
 class Line2D(Artist):
     lineStyles = _lineStyles =  { # hidden names deprecated
         '-'          : '_draw_solid',
@@ -381,12 +343,17 @@
         else:
             x, y = args
 
+        not_masked = 0
         if not ma.isMaskedArray(x):
             x = npy.asarray(x)
+            not_masked += 1
         if not ma.isMaskedArray(y):
             y = npy.asarray(y)
-        if ((x.shape != self._xorig.shape or npy.any(x != self._xorig)) or
-            (y.shape != self._yorig.shape or npy.any(y != self._yorig))):
+            not_masked += 1
+            
+        if (not_masked < 2 or
+            ((x.shape != self._xorig.shape or npy.any(x != self._xorig)) or
+            (y.shape != self._yorig.shape or npy.any(y != self._yorig)))):
             self._xorig = x
             self._yorig = y
             self.recache()

Modified: branches/transforms/lib/matplotlib/patches.py
===================================================================
--- branches/transforms/lib/matplotlib/patches.py       2007-10-25 18:16:03 UTC 
(rev 4003)
+++ branches/transforms/lib/matplotlib/patches.py       2007-10-25 19:16:11 UTC 
(rev 4004)
@@ -224,7 +224,6 @@
 
         path = self.get_path()
         transform = self.get_transform()
-        # MGDTODO: Use a transformed path here?
         tpath = transform.transform_path_non_affine(path)
         affine = transform.get_affine()
         
@@ -328,7 +327,7 @@
 
     def __str__(self):
         return str(self.__class__).split('.')[-1] \
-            + "(%g,%g;%gx%g)"%(self.xy[0],self.xy[1],self.width,self.height)
+            + "(%g,%g;%gx%g)" % tuple(self._bbox.bounds)
 
     def __init__(self, xy, width, height, **kwargs):
         """
@@ -433,7 +432,7 @@
     A regular polygon patch.
     """
     def __str__(self):
-        return "Poly%d(%g,%g)"%(self.numVertices,self.xy[0],self.xy[1])
+        return "Poly%d(%g,%g)"%(self._numVertices,self._xy[0],self._xy[1])
 
     def __init__(self, xy, numVertices, radius=5, orientation=0,
                  **kwargs):
@@ -447,6 +446,7 @@
         %(Patch)s
         """
         self._xy = xy
+        self._numVertices = numVertices
         self._orientation = orientation
         self._radius = radius
        self._path = Path.unit_regular_polygon(numVertices)
@@ -483,6 +483,13 @@
         self._radius = xy
         self._update_transform()
     radius = property(_get_radius, _set_radius)
+
+    def _get_numvertices(self):
+        return self._numVertices
+    def _set_numvertices(self, numVertices):
+        self._numVertices = numVertices
+        self._path = Path.unit_regular_polygon(numVertices)
+    numvertices = property(_get_numvertices, _set_numvertices)
     
     def get_path(self):
        return self._path
@@ -495,7 +502,7 @@
     A general polygon patch.
     """
     def __str__(self):
-        return "Poly(%g, %g)" % tuple(self._path.vertices[0])
+        return "Poly((%g, %g) ...)" % tuple(self._path.vertices[0])
 
     def __init__(self, xy, **kwargs):
         """
@@ -507,15 +514,17 @@
         """
         Patch.__init__(self, **kwargs)
        self._path = Path(xy, closed=True)
-        self.xy = self._path.vertices
     __init__.__doc__ = cbook.dedent(__init__.__doc__) % artist.kwdocd
 
     def get_path(self):
        return self._path
 
-    def update(self):
-        self._path = Path(self.xy, closed=True)
-    
+    def _get_xy(self):
+        return self._path.vertices
+    def _set_xy(self, vertices):
+        self._path = Path(vertices, closed=True)
+    xy = property(_get_xy, _set_xy)
+        
 class Wedge(Patch):
     def __str__(self):
         return "Wedge(%g,%g)"%self.xy[0]
@@ -539,16 +548,14 @@
 
     def get_patch_transform(self):
        return self._patch_transform
-        
+
+# COVERAGE NOTE: Not used internally or from examples
 class Arrow(Polygon):
     """
     An arrow patch
     """
     def __str__(self):
-        x1,y1 = self.xy[0]
-        x2,y2 = self.xy[1]
-        cx,cy = (x1+x2)/2.,(y1+y2)/2.
-        return "Arrow(%g,%g)"%(cx,cy)
+        return "Arrow()"
 
     _path = Path( [
             [ 0.0,  0.1 ], [ 0.0, -0.1],
@@ -584,10 +591,7 @@
     """Like Arrow, but lets you set head width and head height 
independently."""
 
     def __str__(self):
-        x1,y1 = self.xy[0]
-        x2,y2 = self.xy[1]
-        cx,cy = (x1+x2)/2.,(y1+y2)/2.
-        return "FancyArrow(%g,%g)"%(cx,cy)
+        return "FancyArrow()"
 
     def __init__(self, x, y, dx, dy, width=0.001, length_includes_head=False, \
         head_width=None, head_length=None, shape='full', overhang=0, \
@@ -608,7 +612,6 @@
         %(Patch)s
 
         """
-       # MGDTODO: Implement me
         if head_width is None:
             head_width = 3 * width
         if head_length is None:
@@ -664,10 +667,7 @@
     x1,y1 and a base at x2, y2.
     """
     def __str__(self):
-        x1,y1 = self.xy[0]
-        x2,y2 = self.xy[1]
-        cx,cy = (x1+x2)/2.,(y1+y2)/2.
-        return "YAArrow(%g,%g)"%(cx,cy)
+        return "YAArrow()"
 
     def __init__(self, dpi, xytip, xybase, width=4, frac=0.1, headwidth=12, 
**kwargs):
         """
@@ -692,9 +692,8 @@
     __init__.__doc__ = cbook.dedent(__init__.__doc__) % artist.kwdocd
 
     def get_path(self):
-        # MGDTODO: Since this is dpi dependent, we need to recompute
-        # the path every time.  Perhaps this can be plugged through the
-        # dpi transform instead (if only we know how to get it...)
+        # Since this is dpi dependent, we need to recompute the path
+        # every time.
         
         # the base vertices
         x1, y1 = self.xytip
@@ -786,13 +785,16 @@
         """
         Patch.__init__(self, **kwargs)
 
-        self.center = xy
-        self.width, self.height = width, height
-        self.angle = angle
-       self._patch_transform = transforms.Affine2D() \
-           .scale(self.width * 0.5, self.height * 0.5) \
-           .rotate_deg(angle) \
-           .translate(*xy)
+        self._center = xy
+        self._width, self._height = width, height
+        self._angle = angle
+        self._recompute_transform()
+
+    def _recompute_transform(self):
+        self._patch_transform = transforms.Affine2D() \
+           .scale(self._width * 0.5, self._height * 0.5) \
+           .rotate_deg(self._angle) \
+           .translate(*self._center)
         
     def get_path(self):
         """
@@ -808,7 +810,28 @@
         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
@@ -816,8 +839,7 @@
     def __str__(self):
         return 
"Circle((%g,%g),r=%g)"%(self.center[0],self.center[1],self.radius)
 
-    def __init__(self, xy, radius=5,
-                 **kwargs):
+    def __init__(self, xy, radius=5, **kwargs):
         """
         Create true circle at center xy=(x,y) with given radius;
         unlike circle polygon which is a polygonal approcimation, this
@@ -837,122 +859,6 @@
     __init__.__doc__ = cbook.dedent(__init__.__doc__) % artist.kwdocd
 
 
-class PolygonInteractor:
-    """
-    An polygon editor.
-
-    Key-bindings
-
-      't' toggle vertex markers on and off.  When vertex markers are on,
-          you can move them, delete them
-
-      'd' delete the vertex under point
-
-      'i' insert a vertex at point.  You must be within epsilon of the
-          line connecting two existing vertices
-
-    """
-
-    showverts = True
-    epsilon = 5  # max pixel distance to count as a vertex hit
-
-    def __str__(self):
-        return "PolygonInteractor"
-
-    def __init__(self, poly):
-        if poly.figure is None:
-            raise RuntimeError('You must first add the polygon to a figure or 
canvas before defining the interactor')
-        canvas = poly.figure.canvas
-        self.poly = poly
-        self.poly.verts = list(self.poly.verts)
-        x, y = zip(*self.poly.verts)
-        self.line = lines.Line2D(x,y,marker='o', markerfacecolor='r')
-        #self._update_line(poly)
-
-        cid = self.poly.add_callback(self.poly_changed)
-        self._ind = None # the active vert
-
-        canvas.mpl_connect('button_press_event', self.button_press_callback)
-        canvas.mpl_connect('key_press_event', self.key_press_callback)
-        canvas.mpl_connect('button_release_event', 
self.button_release_callback)
-        canvas.mpl_connect('motion_notify_event', self.motion_notify_callback)
-        self.canvas = canvas
-
-
-    def poly_changed(self, poly):
-        'this method is called whenever the polygon object is called'
-        # only copy the artist props to the line (except visibility)
-        vis = self.line.get_visible()
-        artist.Artist.update_from(self.line, poly)
-        self.line.set_visible(vis)  # don't use the poly visibility state
-
-
-    def get_ind_under_point(self, event):
-        'get the index of the vertex under point if within epsilon tolerance'
-        x, y = zip(*self.poly.verts)
-
-        # display coords
-        xt, yt = self.poly.get_transform().numerix_x_y(x, y)
-        d = npy.sqrt((xt-event.x)**2 + (yt-event.y)**2)
-        ind, = npy.nonzero(npy.equal(d, npy.amin(d)))
-
-        if d[ind]>=self.epsilon:
-            ind = None
-
-        return ind
-
-    def button_press_callback(self, event):
-        'whenever a mouse button is pressed'
-        if not self.showverts: return
-        if event.inaxes==None: return
-        if event.button != 1: return
-        self._ind = self.get_ind_under_point(event)
-
-    def button_release_callback(self, event):
-        'whenever a mouse button is released'
-        if not self.showverts: return
-        if event.button != 1: return
-        self._ind = None
-
-    def key_press_callback(self, event):
-        'whenever a key is pressed'
-        if not event.inaxes: return
-        if event.key=='t':
-            self.showverts = not self.showverts
-            self.line.set_visible(self.showverts)
-            if not self.showverts: self._ind = None
-        elif event.key=='d':
-            ind = self.get_ind_under_point(event)
-            if ind is not None:
-                self.poly.verts = [tup for i,tup in enumerate(self.poly.verts) 
if i!=ind]
-                self.line.set_data(zip(*self.poly.verts))
-        elif event.key=='i':
-            xys = self.poly.get_transform().seq_xy_tups(self.poly.verts)
-            p = event.x, event.y # display coords
-            for i in range(len(xys)-1):
-                s0 = xys[i]
-                s1 = xys[i+1]
-                d = mlab.dist_point_to_segment(p, s0, s1)
-                if d<=self.epsilon:
-                    self.poly.verts.insert(i+1, (event.xdata, event.ydata))
-                    self.line.set_data(zip(*self.poly.verts))
-                    break
-
-
-        self.canvas.draw()
-
-    def motion_notify_callback(self, event):
-        'on mouse movement'
-        if not self.showverts: return
-        if self._ind is None: return
-        if event.inaxes is None: return
-        if event.button != 1: return
-        x,y = event.xdata, event.ydata
-        self.poly.verts[self._ind] = x,y
-        self.line.set_data(zip(*self.poly.verts))
-        self.canvas.draw_idle()
-
-
 def bbox_artist(artist, renderer, props=None, fill=True):
     """
     This is a debug function to draw a rectangle around the bounding

Modified: branches/transforms/lib/matplotlib/path.py
===================================================================
--- branches/transforms/lib/matplotlib/path.py  2007-10-25 18:16:03 UTC (rev 
4003)
+++ branches/transforms/lib/matplotlib/path.py  2007-10-25 19:16:11 UTC (rev 
4004)
@@ -405,4 +405,7 @@
     wedge = classmethod(wedge)
 
 def get_path_collection_extents(*args):
+    from transforms import Bbox
+    if len(args[1]) == 0:
+        raise ValueError("No paths provided")
     return Bbox.from_extents(*_path.get_path_collection_extents(*args))

Modified: branches/transforms/lib/matplotlib/scale.py
===================================================================
--- branches/transforms/lib/matplotlib/scale.py 2007-10-25 18:16:03 UTC (rev 
4003)
+++ branches/transforms/lib/matplotlib/scale.py 2007-10-25 19:16:11 UTC (rev 
4004)
@@ -9,8 +9,6 @@
 from transforms import Affine1DBase, IntervalTransform, Transform, \
     composite_transform_factory, IdentityTransform
 
-# MGDTODO: Should the tickers/locators be moved here?
-
 class ScaleBase(object):
     def set_default_locators_and_formatters(self, axis):
         raise NotImplementedError

Modified: branches/transforms/lib/matplotlib/transforms.py
===================================================================
--- branches/transforms/lib/matplotlib/transforms.py    2007-10-25 18:16:03 UTC 
(rev 4003)
+++ branches/transforms/lib/matplotlib/transforms.py    2007-10-25 19:16:11 UTC 
(rev 4004)
@@ -32,7 +32,7 @@
 import cbook
 from path import Path
 
-DEBUG = True
+DEBUG = False
 if DEBUG:
     import warnings
 
@@ -276,7 +276,7 @@
     size = property(_get_size)
     
     def _get_bounds(self):
-        ((x0, y0), (x1, y1)) = self.get_points()
+        x0, y0, x1, y1 = self.get_points().flatten()
         return (x0, y0, x1 - x0, y1 - y0)
     bounds = property(_get_bounds)
 
@@ -608,21 +608,24 @@
         def invalidate(self):
             self._check(self._points)
             TransformNode.invalidate(self)
-        
+
+    _unit_values = npy.array([[0.0, 0.0], [1.0, 1.0]], npy.float_)
     [EMAIL PROTECTED]
     def unit():
         """
         Create a new unit BBox from (0, 0) to (1, 1).
         """
-        return Bbox.from_extents(0., 0., 1., 1.)
+        return Bbox(Bbox._unit_values.copy())
     unit = staticmethod(unit)
 
     [EMAIL PROTECTED]
-    def from_bounds(left, bottom, width, height):
+    def from_bounds(x0, y0, width, height):
         """
-        Create a new Bbox from left, bottom, width and height.
+        Create a new Bbox from x0, y0, width and height.
+
+        width and height may be negative.
         """
-        return Bbox.from_extents(left, bottom, left + width, bottom + height)
+        return Bbox.from_extents(x0, y0, x0 + width, y0 + height)
     from_bounds = staticmethod(from_bounds)
 
     [EMAIL PROTECTED]
@@ -663,7 +666,6 @@
            when False, include the existing bounds of the Bbox.
            when None, use the last value passed to Bbox.ignore().
         """
-        # MGDTODO: It may be more efficient for some callers to use 
update_from_data_xy instead
         if ignore is None:
             ignore = self._ignore
 
@@ -830,7 +832,11 @@
     
     def get_points(self):
         if self._invalid:
-            self._points = self._transform.transform(self._bbox.get_points())
+            points = self._transform.transform(self._bbox.get_points())
+            if ma.isMaskedArray(points):
+                points.putmask(0.0)
+                points = npy.asarray(points)
+            self._points = points
             self._invalid = 0
         return self._points
 
@@ -1429,8 +1435,8 @@
     if DEBUG:
         _transform = transform
         def transform(self, points):
-            # MGDTODO: The major speed trap here is just converting to
-            # the points to an array in the first place.  If we can use
+            # The major speed trap here is just converting to the
+            # points to an array in the first place.  If we can use
             # more arrays upstream, that should help here.
             if (not ma.isMaskedArray(points) and
                 not isinstance(points, npy.ndarray)):
@@ -2074,7 +2080,7 @@
         """
         assert boxin.is_bbox
         assert boxout.is_bbox
-
+        
         Affine2DBase.__init__(self)
         self._boxin = boxin
         self._boxout = boxout
@@ -2092,6 +2098,8 @@
             outl, outb, outw, outh = self._boxout.bounds
             x_scale = outw / inw
             y_scale = outh / inh
+            if DEBUG and (x_scale == 0 or y_scale == 0):
+                raise ValueError("Transforming from or to a singular bounding 
box.")
             self._mtx = npy.array([[x_scale, 0.0    , (-inl*x_scale+outl)],
                                    [0.0    , y_scale, (-inb*y_scale+outb)],
                                    [0.0    , 0.0    , 1.0        ]],
@@ -2175,18 +2183,17 @@
     return vmin, vmax
 
 
-# MGDTODO: Optimize (perhaps in an extension)
 def interval_contains(interval, val):
     a, b = interval
-    return (((a < b)
-             and (a <= val and b >= val))
-            or (b <= val and a >= val))
+    return (
+        ((a < b) and (a <= val and b >= val))
+        or (b <= val and a >= val))
 
 def interval_contains_open(interval, val):
     a, b = interval
-    return (((a < b)
-             and (a < val and b > val))
-            or (b < val and a > val))
+    return (
+        ((a < b) and (a < val and b > val))
+        or (b < val and a > val))
     
 if __name__ == '__main__':
     import copy

Modified: branches/transforms/lib/matplotlib/widgets.py
===================================================================
--- branches/transforms/lib/matplotlib/widgets.py       2007-10-25 18:16:03 UTC 
(rev 4003)
+++ branches/transforms/lib/matplotlib/widgets.py       2007-10-25 19:16:11 UTC 
(rev 4004)
@@ -240,9 +240,10 @@
         self.set_val(val)
 
     def set_val(self, val):
-        self.poly.xy[-1] = val, 0
-        self.poly.xy[-2] = val, 1
-        self.poly.update()
+        xy = self.poly.xy
+        xy[-1] = val, 0
+        xy[-2] = val, 1
+        self.poly.xy = xy
         self.valtext.set_text(self.valfmt%val)
         if self.drawon: self.ax.figure.canvas.draw()
         self.val = val

Modified: branches/transforms/src/_gtkagg.cpp
===================================================================
--- branches/transforms/src/_gtkagg.cpp 2007-10-25 18:16:03 UTC (rev 4003)
+++ branches/transforms/src/_gtkagg.cpp 2007-10-25 19:16:11 UTC (rev 4004)
@@ -70,7 +70,6 @@
     }
     else {
       //bbox is not None; copy the image in the bbox
-      // MGDTODO: Use PyArray rather than buffer interface here
       PyObject* clipbox = args[2].ptr();
       PyArrayObject* bbox = NULL;
       double l, b, r, t;


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