Revision: 3889
          http://matplotlib.svn.sourceforge.net/matplotlib/?rev=3889&view=rev
Author:   mdboom
Date:     2007-09-25 10:04:51 -0700 (Tue, 25 Sep 2007)

Log Message:
-----------
Automaticall separate affine from non-affine transforms

Modified Paths:
--------------
    branches/transforms/lib/matplotlib/axes.py
    branches/transforms/lib/matplotlib/axis.py
    branches/transforms/lib/matplotlib/backends/backend_agg.py
    branches/transforms/lib/matplotlib/lines.py
    branches/transforms/lib/matplotlib/path.py
    branches/transforms/lib/matplotlib/scale.py
    branches/transforms/lib/matplotlib/ticker.py
    branches/transforms/lib/matplotlib/transforms.py

Modified: branches/transforms/lib/matplotlib/axes.py
===================================================================
--- branches/transforms/lib/matplotlib/axes.py  2007-09-25 12:15:22 UTC (rev 
3888)
+++ branches/transforms/lib/matplotlib/axes.py  2007-09-25 17:04:51 UTC (rev 
3889)
@@ -545,7 +545,7 @@
         "move this out of __init__ because non-separable axes don't use it"
         self.xaxis = maxis.XAxis(self)
         self.yaxis = maxis.YAxis(self)
-        self._update_transAxisXY()
+        self._update_transScale()
 
     def sharex_foreign(self, axforeign):
         """
@@ -631,12 +631,28 @@
         self.viewLim = mtransforms.Bbox.unit()
         self.transAxes = mtransforms.BboxTransform(
             mtransforms.Bbox.unit(), self.bbox)
-        self.transAxisXY = mtransforms.TransformWrapper()
-        self.transData = self.transAxisXY + self.transAxes
 
-    def _update_transAxisXY(self):
-        self.transAxisXY.set(mtransforms.blended_transform_factory(
+        # Transforms the x and y axis separately by a scale factor
+        # It is assumed that this part will have non-linear components
+        self.transScale = 
mtransforms.TransformWrapper(mtransforms.IdentityTransform())
+
+        # A (possibly non-linear) projection on the (already scaled) data
+        self.transProjection = mtransforms.IdentityTransform()
+
+        # An affine transformation on the data, generally to limit the
+        # range of the axes
+        self.transLimits = mtransforms.BboxTransform(
+            mtransforms.TransformedBbox(self.viewLim, self.transScale), 
mtransforms.Bbox.unit())
+        
+        self.transData = self.transScale + self.transProjection + 
self.transLimits + self.transAxes
+
+
+    def _update_transScale(self):
+        self.transScale.set(
+            mtransforms.blended_transform_factory(
                 self.xaxis.get_transform(), self.yaxis.get_transform()))
+
+        self.transData.make_graphviz(open("trans.dot", "w"))
         
     def get_position(self, original=False):
         'Return the axes rectangle left, bottom, width, height'
@@ -1537,7 +1553,7 @@
         ACCEPTS: ['log' | 'linear' ]
         """
         self.xaxis.set_scale(value, **kwargs)
-        self._update_transAxisXY()
+        self._update_transScale()
         
     def get_xticks(self):
         'Return the x ticks as a list of locations'
@@ -1647,7 +1663,7 @@
         ACCEPTS: ['log' | 'linear']
         """
         self.yaxis.set_scale(value, basey, subsy)
-        self._update_transAxisXY()
+        self._update_transScale()
         
     def get_yticks(self):
         'Return the y ticks as a list of locations'

Modified: branches/transforms/lib/matplotlib/axis.py
===================================================================
--- branches/transforms/lib/matplotlib/axis.py  2007-09-25 12:15:22 UTC (rev 
3888)
+++ branches/transforms/lib/matplotlib/axis.py  2007-09-25 17:04:51 UTC (rev 
3889)
@@ -508,16 +508,15 @@
         self.majorTicks = []
         self.minorTicks = []
         self.pickradius = pickradius
-        self._transform = LinearScale(self.axes.viewLim, 
self.axis).get_transform()
-        self._scale = 'linear'
+        self._scale = LinearScale()
         
         self.cla()
 
     def get_transform(self):
-        return self._transform
-
+        return self._scale.get_transform()
+    
     def get_scale(self):
-        return self._scale
+        return self._scale.name
     
     def set_scale(self, value, base=10, subs=None):
         # MGDTODO: Move these settings (ticker etc.) into the scale class 
itself
@@ -528,17 +527,16 @@
             self.set_major_formatter(ScalarFormatter())
             self.set_minor_locator(NullLocator())
             self.set_minor_formatter(NullFormatter())
-            self._transform = LinearScale(self.axes.viewLim, 
self.axis).get_transform()
+            self._scale = LinearScale()
         elif value == 'log':
             self.set_major_locator(LogLocator(base))
             self.set_major_formatter(LogFormatterMathtext(base))
             self.set_minor_locator(LogLocator(base,subs))
             # MGDTODO: Pass base along
-            self._transform = LogScale(self.axes.viewLim, 
self.axis).get_transform()
+            self._scale = LogScale()
             miny, maxy = getattr(self.axes.viewLim, 'interval' + self.axis)
             if min(miny, maxy)<=0:
                 self.axes.autoscale_view()
-        self._scale = value
                 
     def get_children(self):
         children = [self.label]

Modified: branches/transforms/lib/matplotlib/backends/backend_agg.py
===================================================================
--- branches/transforms/lib/matplotlib/backends/backend_agg.py  2007-09-25 
12:15:22 UTC (rev 3888)
+++ branches/transforms/lib/matplotlib/backends/backend_agg.py  2007-09-25 
17:04:51 UTC (rev 3889)
@@ -132,14 +132,14 @@
 
     # MGDTODO: This is a hack for now to allow for arbitrary transformations
     def draw_path(self, gc, path, trans, rgbFace=None):
-        new_path, affine = path.transformed_without_affine(trans)
-        self._renderer.draw_path(gc, new_path, affine, rgbFace)
+        assert trans.is_affine()
+        self._renderer.draw_path(gc, path, trans, rgbFace)
 
     # MGDTODO: This is a hack for now to allow for arbitrary transformations
     def draw_markers(self, gc, marker_path, marker_trans, path, trans, 
rgbFace=None):
         assert marker_trans.is_affine()
-        new_path, affine = path.transformed_without_affine(trans)
-        self._renderer.draw_markers(gc, marker_path, marker_trans, new_path, 
affine, rgbFace)
+        assert trans.is_affine()
+        self._renderer.draw_markers(gc, marker_path, marker_trans, path, 
trans, rgbFace)
         
     def draw_mathtext(self, gc, x, y, s, prop, angle):
         """

Modified: branches/transforms/lib/matplotlib/lines.py
===================================================================
--- branches/transforms/lib/matplotlib/lines.py 2007-09-25 12:15:22 UTC (rev 
3888)
+++ branches/transforms/lib/matplotlib/lines.py 2007-09-25 17:04:51 UTC (rev 
3889)
@@ -17,7 +17,7 @@
 from cbook import iterable, is_string_like, is_numlike
 from colors import colorConverter
 from path import Path
-from transforms import Affine2D, Bbox
+from transforms import Affine2D, Bbox, TransformedPath
 
 from matplotlib import rcParams
 
@@ -416,8 +416,18 @@
         self._logcache = None
         # Masked arrays are now handled by the Path class itself
         self._path = Path(self._xy, closed=False)
+        self._transformed_path = TransformedPath(self._path, 
self.get_transform())
         # MGDTODO: If _draw_steps is removed, remove the following line also
         self._step_path = None
+
+    def set_transform(self, t):
+        """
+        set the Transformation instance used by this artist
+
+        ACCEPTS: a matplotlib.transform transformation instance
+        """
+        Artist.set_transform(self, t)
+        self._transformed_path = TransformedPath(self._path, 
self.get_transform())
         
     def _is_sorted(self, x):
         "return true if x is sorted"
@@ -486,10 +496,10 @@
 
         funcname = self._lineStyles.get(self._linestyle, '_draw_nothing')
         lineFunc = getattr(self, funcname)
-        lineFunc(renderer, gc, self._path)
+        lineFunc(renderer, gc, *self._transformed_path.get_path_and_affine())
            
        # MGDTODO: Deal with markers
-        if self._marker is not None:
+        if self._marker is not None and False:
             gc = renderer.new_gc()
             self._set_gc_clip(gc)
             gc.set_foreground(self.get_markeredgecolor())
@@ -678,7 +688,7 @@
             self.set_linestyle('--')
         self._dashSeq = seq  # TODO: offset ignored for now
 
-    def _draw_nothing(self, renderer, gc, path):
+    def _draw_nothing(self, *args, **kwargs):
         pass
 
 
@@ -704,191 +714,191 @@
        renderer.draw_path(gc, self._step_path, self.get_transform())
 
         
-    def _draw_solid(self, renderer, gc, path):
+    def _draw_solid(self, renderer, gc, path, trans):
         gc.set_linestyle('solid')
-       renderer.draw_path(gc, path, self.get_transform())
+       renderer.draw_path(gc, path, trans)
 
 
-    def _draw_dashed(self, renderer, gc, path):
+    def _draw_dashed(self, renderer, gc, path, trans):
         gc.set_linestyle('dashed')
         if self._dashSeq is not None:
             gc.set_dashes(0, self._dashSeq)
 
-       renderer.draw_path(gc, path, self.get_transform())
+       renderer.draw_path(gc, path, trans)
 
 
-    def _draw_dash_dot(self, renderer, gc, path):
+    def _draw_dash_dot(self, renderer, gc, path, trans):
         gc.set_linestyle('dashdot')
-       renderer.draw_path(gc, path, self.get_transform())
+       renderer.draw_path(gc, path, trans)
 
            
-    def _draw_dotted(self, renderer, gc, path):
+    def _draw_dotted(self, renderer, gc, path, trans):
         gc.set_linestyle('dotted')
-       renderer.draw_path(gc, path, self.get_transform())
+       renderer.draw_path(gc, path, trans)
 
        
-    def _draw_point(self, renderer, gc, path):
+    def _draw_point(self, renderer, gc, path, path_trans):
         w = renderer.points_to_pixels(self._markersize) * \
            self._point_size_reduction * 0.5
         rgbFace = self._get_rgb_face()
        transform = Affine2D().scale(w)
        renderer.draw_markers(
-           gc, Path.unit_circle(), transform, path, self.get_transform(),
+           gc, Path.unit_circle(), transform, path, path_trans,
            rgbFace)
 
        
-    def _draw_pixel(self, renderer, gc, path):
+    def _draw_pixel(self, renderer, gc, path, path_trans):
        rgbFace = self._get_rgb_face()
        transform = Affine2D().translate(-0.5, -0.5)
        renderer.draw_markers(gc, Path.unit_rectangle, transform,
-                             path, self.get_transform(), rgbFace)
+                             path, path_trans, rgbFace)
        
        
-    def _draw_circle(self, renderer, gc, path):
+    def _draw_circle(self, renderer, gc, path, path_trans):
         w = renderer.points_to_pixels(self._markersize) * 0.5
         rgbFace = self._get_rgb_face()
        transform = Affine2D().scale(w, w)
        renderer.draw_markers(
-           gc, Path.unit_circle(), transform, path, self.get_transform(),
+           gc, Path.unit_circle(), transform, path, path_trans,
            rgbFace)
 
 
     _triangle_path = Path([[0.0, 1.0], [-1.0, -1.0], [1.0, -1.0]])
-    def _draw_triangle_up(self, renderer, gc, path):
+    def _draw_triangle_up(self, renderer, gc, path, path_trans):
         offset = 0.5*renderer.points_to_pixels(self._markersize)
        transform = Affine2D().scale(offset, offset)
         rgbFace = self._get_rgb_face()
        renderer.draw_markers(gc, self._triangle_path, transform,
-                             path, self.get_transform(), rgbFace)
+                             path, path_trans, rgbFace)
 
 
-    def _draw_triangle_down(self, renderer, gc, path):
+    def _draw_triangle_down(self, renderer, gc, path, path_trans):
         offset = 0.5*renderer.points_to_pixels(self._markersize)
        transform = Affine2D().scale(offset, -offset)
         rgbFace = self._get_rgb_face()
        renderer.draw_markers(gc, self._triangle_path, transform,
-                             path, self.get_transform(), rgbFace)
+                             path, path_trans, rgbFace)
 
        
-    def _draw_triangle_left(self, renderer, gc, path):
+    def _draw_triangle_left(self, renderer, gc, path, path_trans):
         offset = 0.5*renderer.points_to_pixels(self._markersize)
        transform = Affine2D().scale(offset, offset).rotate_deg(90)
         rgbFace = self._get_rgb_face()
        renderer.draw_markers(gc, self._triangle_path, transform,
-                             path, self.get_transform(), rgbFace)
+                             path, path_trans, rgbFace)
 
 
-    def _draw_triangle_right(self, renderer, gc, path):
+    def _draw_triangle_right(self, renderer, gc, path, path_trans):
         offset = 0.5*renderer.points_to_pixels(self._markersize)
        transform = Affine2D().scale(offset, offset).rotate_deg(-90)
         rgbFace = self._get_rgb_face()
        renderer.draw_markers(gc, self._triangle_path, transform,
-                             path, self.get_transform(), rgbFace)
+                             path, path_trans, rgbFace)
 
 
-    def _draw_square(self, renderer, gc, path):
+    def _draw_square(self, renderer, gc, path, path_trans):
         side = renderer.points_to_pixels(self._markersize)
        transform = Affine2D().translate(-0.5, -0.5).scale(side)
         rgbFace = self._get_rgb_face()
        renderer.draw_markers(gc, Path.unit_rectangle(), transform,
-                             path, self.get_transform(), rgbFace)
+                             path, path_trans, rgbFace)
 
        
-    def _draw_diamond(self, renderer, gc, path):
+    def _draw_diamond(self, renderer, gc, path, path_trans):
         side = renderer.points_to_pixels(self._markersize)
        transform = Affine2D().translate(0.5, 0.5).rotate_deg(45).scale(side)
         rgbFace = self._get_rgb_face()
        renderer.draw_markers(gc, Path.unit_rectangle(), transform,
-                             path, self.get_transform(), rgbFace)
+                             path, path_trans, rgbFace)
 
        
-    def _draw_thin_diamond(self, renderer, gc, path):
+    def _draw_thin_diamond(self, renderer, gc, path, path_trans):
         offset = renderer.points_to_pixels(self._markersize)
        transform = Affine2D().translate(0.5, 0.5) \
            .rotate_deg(45).scale(offset * 0.8, offset)
         rgbFace = self._get_rgb_face()
        renderer.draw_markers(gc, Path.unit_rectangle(), transform,
-                             path, self.get_transform(), rgbFace)
+                             path, path_trans, rgbFace)
 
        
-    def _draw_pentagon(self, renderer, gc, path):
+    def _draw_pentagon(self, renderer, gc, path, path_trans):
         offset = 0.5 * renderer.points_to_pixels(self._markersize)
        transform = Affine2D().scale(offset)
        rgbFace = self._get_rgb_face()
        renderer.draw_markers(gc, Path.unit_regular_polygon(5), transform,
-                             path, self.get_transform(), rgbFace)
+                             path, path_trans, rgbFace)
 
        
-    def _draw_hexagon1(self, renderer, gc, path):
+    def _draw_hexagon1(self, renderer, gc, path, path_trans):
         offset = 0.5 * renderer.points_to_pixels(self._markersize)
        transform = Affine2D().scale(offset)
        rgbFace = self._get_rgb_face()
        renderer.draw_markers(gc, Path.unit_regular_polygon(6), transform,
-                             path, self.get_transform(), rgbFace)
+                             path, path_trans, rgbFace)
 
        
-    def _draw_hexagon2(self, renderer, gc, path):
+    def _draw_hexagon2(self, renderer, gc, path, path_trans):
         offset = 0.5 * renderer.points_to_pixels(self._markersize)
        transform = Affine2D().scale(offset).rotate_deg(30)
        rgbFace = self._get_rgb_face()
        renderer.draw_markers(gc, Path.unit_regular_polygon(6), transform,
-                             path, self.get_transform(), rgbFace)
+                             path, path_trans, rgbFace)
 
 
     _line_marker_path = Path([[0.0, -1.0], [0.0, 1.0]], closed=False)
-    def _draw_vline(self, renderer, gc, path):
+    def _draw_vline(self, renderer, gc, path, path_trans):
         offset = 0.5*renderer.points_to_pixels(self._markersize)
        transform = Affine2D().scale(offset)
        renderer.draw_markers(gc, self._line_marker_path, transform,
-                             path, self.get_transform())
+                             path, path_trans)
 
                
-    def _draw_hline(self, renderer, gc, path):
+    def _draw_hline(self, renderer, gc, path, path_trans):
         offset = 0.5*renderer.points_to_pixels(self._markersize)
        transform = Affine2D().scale(offset).rotate_deg(90)
        renderer.draw_markers(gc, self._line_marker_path, transform,
-                             path, self.get_transform())
+                             path, path_trans)
 
                
     _tickhoriz_path = Path([[0.0, 0.5], [1.0, 0.5]], closed=False)
-    def _draw_tickleft(self, renderer, gc, path):
+    def _draw_tickleft(self, renderer, gc, path, path_trans):
         offset = renderer.points_to_pixels(self._markersize)
        marker_transform = Affine2D().scale(-offset, 1.0)
        renderer.draw_markers(gc, self._tickhoriz_path, marker_transform,
-                             path, self.get_transform())
+                             path, path_trans)
 
        
-    def _draw_tickright(self, renderer, gc, path):
+    def _draw_tickright(self, renderer, gc, path, path_trans):
         offset = renderer.points_to_pixels(self._markersize)
        marker_transform = Affine2D().scale(offset, 1.0)
        renderer.draw_markers(gc, self._tickhoriz_path, marker_transform,
-                             path, self.get_transform())
+                             path, path_trans)
 
        
     _tickvert_path = Path([[-0.5, 0.0], [-0.5, 1.0]], closed=False)
-    def _draw_tickup(self, renderer, gc, path):
+    def _draw_tickup(self, renderer, gc, path, path_trans):
         offset = renderer.points_to_pixels(self._markersize)
        marker_transform = Affine2D().scale(1.0, offset)
        renderer.draw_markers(gc, self._tickvert_path, marker_transform,
-                             path, self.get_transform())
+                             path, path_trans)
 
        
-    def _draw_tickdown(self, renderer, gc, path):
+    def _draw_tickdown(self, renderer, gc, path, path_trans):
         offset = renderer.points_to_pixels(self._markersize)
        marker_transform = Affine2D().scale(1.0, -offset)
        renderer.draw_markers(gc, self._tickvert_path, marker_transform,
-                             path, self.get_transform())
+                             path, path_trans)
 
 
     _plus_path = Path([[-1.0, 0.0], [1.0, 0.0],
                       [0.0, -1.0], [0.0, 1.0]],
                      [Path.MOVETO, Path.LINETO,
                       Path.MOVETO, Path.LINETO])
-    def _draw_plus(self, renderer, gc, path):
+    def _draw_plus(self, renderer, gc, path, path_trans):
         offset = 0.5*renderer.points_to_pixels(self._markersize)
        transform = Affine2D().scale(offset)
        renderer.draw_markers(gc, self._plus_path, transform,
-                             path, self.get_transform())
+                             path, path_trans)
 
 
     _tri_path = Path([[0.0, 0.0], [0.0, -1.0],
@@ -897,61 +907,61 @@
                     [Path.MOVETO, Path.LINETO,
                      Path.MOVETO, Path.LINETO,
                      Path.MOVETO, Path.LINETO])
-    def _draw_tri_down(self, renderer, gc, path):
+    def _draw_tri_down(self, renderer, gc, path, path_trans):
         offset = 0.5*renderer.points_to_pixels(self._markersize)
        transform = Affine2D().scale(offset)
        renderer.draw_markers(gc, self._tri_path, transform,
-                             path, self.get_transform())
+                             path, path_trans)
 
        
-    def _draw_tri_up(self, renderer, gc, path):
+    def _draw_tri_up(self, renderer, gc, path, path_trans):
         offset = 0.5*renderer.points_to_pixels(self._markersize)
        transform = Affine2D().scale(offset).rotate_deg(180)
        renderer.draw_markers(gc, self._tri_path, transform,
-                             path, self.get_transform())
+                             path, path_trans)
 
        
-    def _draw_tri_left(self, renderer, gc, path):
+    def _draw_tri_left(self, renderer, gc, path, path_trans):
        offset = 0.5*renderer.points_to_pixels(self._markersize)
        transform = Affine2D().scale(offset).rotate_deg(90)
        renderer.draw_markers(gc, self._tri_path, transform,
-                             path, self.get_transform())
+                             path, path_trans)
 
        
-    def _draw_tri_right(self, renderer, gc, path):
+    def _draw_tri_right(self, renderer, gc, path, path_trans):
        offset = 0.5*renderer.points_to_pixels(self._markersize)
        transform = Affine2D().scale(offset).rotate_deg(270)
        renderer.draw_markers(gc, self._tri_path, transform,
-                             path, self.get_transform())
+                             path, path_trans)
 
 
     _caret_path = Path([[-1.0, 1.5], [0.0, 0.0], [1.0, 1.5]], closed=False)
-    def _draw_caretdown(self, renderer, gc, path):
+    def _draw_caretdown(self, renderer, gc, path, path_trans):
         offset = 0.5*renderer.points_to_pixels(self._markersize)
        transform = Affine2D().scale(offset)
        renderer.draw_markers(gc, self._caret_path, transform,
-                             path, self.get_transform())
+                             path, path_trans)
 
        
-    def _draw_caretup(self, renderer, gc, path):
+    def _draw_caretup(self, renderer, gc, path, path_trans):
         offset = 0.5*renderer.points_to_pixels(self._markersize)
        transform = Affine2D().scale(offset).rotate_deg(180)
        renderer.draw_markers(gc, self._caret_path, transform,
-                             path, self.get_transform())
+                             path, path_trans)
 
        
-    def _draw_caretleft(self, renderer, gc, path):
+    def _draw_caretleft(self, renderer, gc, path, path_trans):
         offset = 0.5*renderer.points_to_pixels(self._markersize)
        transform = Affine2D().scale(offset).rotate_deg(90)
        renderer.draw_markers(gc, self._caret_path, transform,
-                             path, self.get_transform())
+                             path, path_trans)
 
        
-    def _draw_caretright(self, renderer, gc, path):
+    def _draw_caretright(self, renderer, gc, path, path_trans):
         offset = 0.5*renderer.points_to_pixels(self._markersize)
        transform = Affine2D().scale(offset).rotate_deg(270)
        renderer.draw_markers(gc, self._caret_path, transform,
-                             path, self.get_transform())
+                             path, path_trans)
 
 
     _x_path = Path([[-1.0, -1.0], [1.0, 1.0],
@@ -962,7 +972,7 @@
         offset = 0.5*renderer.points_to_pixels(self._markersize)
        transform = Affine2D().scale(offset)
        renderer.draw_markers(gc, self._x_path, transform,
-                             path, self.get_transform())
+                             path, path_trans)
 
        
     def update_from(self, other):

Modified: branches/transforms/lib/matplotlib/path.py
===================================================================
--- branches/transforms/lib/matplotlib/path.py  2007-09-25 12:15:22 UTC (rev 
3888)
+++ branches/transforms/lib/matplotlib/path.py  2007-09-25 17:04:51 UTC (rev 
3889)
@@ -88,10 +88,6 @@
 
     def transformed(self, transform):
         return Path(transform.transform(self.vertices), self.codes)
-
-    def transformed_without_affine(self, transform):
-        vertices, affine = transform.transform_without_affine(self.vertices)
-        return Path(vertices, self.codes), affine
                 
     _unit_rectangle = None
     [EMAIL PROTECTED]
@@ -152,6 +148,3 @@
            cls._unit_circle = Path(vertices, codes)
        return cls._unit_circle
     unit_circle = classmethod(unit_circle)
-
-# MGDTODO: Add a transformed path that would automatically invalidate
-# itself when its transform changes

Modified: branches/transforms/lib/matplotlib/scale.py
===================================================================
--- branches/transforms/lib/matplotlib/scale.py 2007-09-25 12:15:22 UTC (rev 
3888)
+++ branches/transforms/lib/matplotlib/scale.py 2007-09-25 17:04:51 UTC (rev 
3889)
@@ -1,66 +1,54 @@
 import numpy as npy
 from numpy import ma
+from numpy.linalg import inv
 
-from transforms import Affine1D, IntervalTransform, Transform
+from transforms import Affine1DBase, IntervalTransform, Transform, \
+    composite_transform_factory, IdentityTransform
 
 class ScaleBase(object):
     pass
 
 class LinearScale(ScaleBase):
-    def __init__(self, viewLim, direction):
-        direction = 'interval' + direction
-        self._transform = IntervalTransform(viewLim, direction)
-
     def get_transform(self):
-        return self._transform
+        return IdentityTransform()
         
 class LogScale(ScaleBase):
     class LogTransform(Transform):
         input_dims = 1
         output_dims = 1
-        def __init__(self, viewLim, direction, base):
+        def __init__(self, base):
             Transform.__init__(self)
             self._base = base
-            self._viewLim = viewLim
-            self._direction = direction
-            self.set_children(['_viewLim'])
 
+        def is_separable(self):
+            return True
+            
         def transform(self, a):
-            a, affine = self.transform_without_affine(a)
-            return affine.transform(a)
+            if len(a) > 10:
+                print "Log Transforming..."
+            return ma.log10(ma.masked_where(a <= 0.0, a * 10.0))
             
-        def transform_without_affine(self, a):
-            # MGDTODO: Support different bases
-            base = self._base
-            marray = ma.masked_where(a <= 0.0, a * 10.0)
-            marray = npy.log10(marray)
-            minimum, maximum = npy.log10(getattr(self._viewLim, 
self._direction) * 10.0)
-            return marray, Affine1D.from_values(maximum - minimum, 
minimum).inverted()
-            
         def inverted(self):
-            return LogScale.InvertedLogTransform(self._viewLim, 
self._direction, self._base)
+            return LogScale.InvertedLogTransform(self._base)
 
     class InvertedLogTransform(Transform):
         input_dims = 1
         output_dims = 1
-        def __init__(self, viewLim, direction, base):
+        def __init__(self, base):
             Transform.__init__(self)
             self._base = base
-            self._viewLim = viewLim
-            self._direction = direction
-            self.set_children(['_viewLim'])
+
+        def is_separable(self):
+            return True
             
         def transform(self, a):
-            minimum, maximum = npy.log10(getattr(self._viewLim, 
self._direction) * 10.0)
-            a = Affine1D.from_values(maximum - minimum, minimum).transform(a)
             return ma.power(10.0, a) / 10.0
 
         def inverted(self):
-            return LogScale.LogTransform(self._viewLim, self._direction, 
self._base)
+            return LogScale.LogTransform(self._base)
             
-    def __init__(self, viewLim, direction, base=10):
-        direction = 'interval' + direction
-        self._transform = self.LogTransform(viewLim, direction, base)
+    def __init__(self, base=10):
+        self._transform = self.LogTransform(base)
 
     def get_transform(self):
         return self._transform

Modified: branches/transforms/lib/matplotlib/ticker.py
===================================================================
--- branches/transforms/lib/matplotlib/ticker.py        2007-09-25 12:15:22 UTC 
(rev 3888)
+++ branches/transforms/lib/matplotlib/ticker.py        2007-09-25 17:04:51 UTC 
(rev 3889)
@@ -937,9 +937,7 @@
         if vmin==vmax:
             vmin = decade_down(vmin,self._base)
             vmax = decade_up(vmax,self._base)
-        print vmin, vmax
         result = mtransforms.nonsingular(vmin, vmax)
-        print result
         return result
 
 class AutoLocator(MaxNLocator):

Modified: branches/transforms/lib/matplotlib/transforms.py
===================================================================
--- branches/transforms/lib/matplotlib/transforms.py    2007-09-25 12:15:22 UTC 
(rev 3888)
+++ branches/transforms/lib/matplotlib/transforms.py    2007-09-25 17:04:51 UTC 
(rev 3889)
@@ -8,7 +8,10 @@
 from numpy import ma as ma
 from numpy.linalg import inv
 from sets import Set
+from weakref import WeakKeyDictionary
 
+from path import Path
+
 DEBUG = False
 
 # MGDTODO: This creates a ton of cyclical references.  We may want to
@@ -22,45 +25,54 @@
         self._parents = Set()
         self._children = []
         
-    def invalidate(self):
-        self._do_invalidation()
+    def invalidate(self, which_child=None, affine_only=[]):
+        if which_child is None:
+            which_child = self
+        self._do_invalidation(which_child, affine_only)
+        # affine_only = affine_only and (self.is_affine() or self.is_bbox())
         for parent in self._parents:
-            parent.invalidate()
+            parent.invalidate(self, affine_only + [self])
 
-    def _do_invalidation(self):
-        return False
-
+    def _do_invalidation(self, which_child, affine_only):
+        pass
+        
     def set_children(self, children):
         for child in children:
             getattr(self, child)._parents.add(self)
         self._children = children
 
     def make_graphviz(self, fobj):
+        seen = Set()
+
         def recurse(root):
+            if root in seen:
+                return
+            seen.add(root)
             fobj.write('%s [label="%s"];\n' %
                        (hash(root), root.__class__.__name__))
-            if isinstance(root, Affine2DBase):
+            if root.is_affine():
                 fobj.write('%s [style=filled, color=".7 .7 .9"];\n' %
                            hash(root))
-            elif isinstance(root, BboxBase):
+            elif root.is_bbox():
                 fobj.write('%s [style=filled, color=".9 .9 .7"];\n' %
                            hash(root))
             for child_name in root._children:
                 child = getattr(root, child_name)
-                fobj.write("%s -> %s;\n" % (
+                fobj.write('%s -> %s [label="%s"];\n' % (
                         hash(root),
-                        hash(child)))
+                        hash(child),
+                        child_name))
                 recurse(child)
-        
+
         fobj.write("digraph G {\n")
         recurse(self)
         fobj.write("}\n")
         
     def is_affine(self):
-        return isinstance(self, Affine2DBase)
+        return False
 
     def is_bbox(self):
-        return isinstance(self, BboxBase)
+        return False
 
     
 class BboxBase(TransformNode):
@@ -70,7 +82,10 @@
     
     def __init__(self):
         TransformNode.__init__(self)
-    
+
+    def is_bbox(self):
+        return True
+        
     def __array__(self):
         return self.get_points()
 
@@ -125,63 +140,81 @@
     height = property(_get_height)
 
     def _get_bounds(self):
-        return (self.xmin, self.ymin,
-                self.xmax - self.xmin, self.ymax - self.ymin)
+        ((xmin, ymin), (xmax, ymax)) = self.get_points()
+        return (xmin, ymin, xmax - xmin, ymax - ymin)
     bounds = property(_get_bounds)
 
+    def _get_lbrt(self):
+        return self.get_points().flatten().copy()
+    lbrt = property(_get_lbrt)
+    
     def get_points(self):
         return NotImplementedError()
-
+    
     # MGDTODO: Optimize
     def containsx(self, x):
-        return x >= self.xmin and x <= self.xmax
+        xmin, xmax = self.intervalx
+        return x >= xmin and x <= xmax
 
     def containsy(self, y):
-        return y >= self.ymin and y <= self.ymax
+        ymin, ymax = self.intervaly
+        return y >= ymin and y <= ymax
     
     def contains(self, x, y):
         return self.containsx(x) and self.containsy(y)
 
     def overlapsx(self, other):
-        return self.containsx(other.xmin) \
-            or self.containsx(other.xmax)
+        xmin, xmax = other.intervalx
+        return self.containsx(xmin) \
+            or self.containsx(xmax)
 
     def overlapsy(self, other):
-        return self.containsy(other.ymin) \
-            or self.containsx(other.ymax)
+        ymin, ymax = other.intervaly
+        return self.containsy(ymin) \
+            or self.containsx(ymax)
     
     def overlaps(self, other):
         return self.overlapsx(other) \
             and self.overlapsy(other)
     
     def fully_containsx(self, x):
-        return x > self.xmin and x < self.xmax
+        xmin, xmax = self.intervalx
+        return x > xmin and x < xmax
 
     def fully_containsy(self, y):
-        return y > self.ymin and y < self.ymax
+        ymin, ymax = self.intervaly
+        return y > ymin and y < ymax
     
     def fully_contains(self, x, y):
         return self.fully_containsx(x) \
             and self.fully_containsy(y)
 
     def fully_overlapsx(self, other):
-        return self.fully_containsx(other.xmin) \
-            or self.fully_containsx(other.xmax)
+        xmin, xmax = other.intervalx
+        return self.fully_containsx(xmin) \
+            or self.fully_containsx(xmax)
 
     def fully_overlapsy(self, other):
-        return self.fully_containsy(other.ymin) \
-            or self.fully_containsx(other.ymax)
+        ymin, ymax = other.intervaly
+        return self.fully_containsy(ymin) \
+            or self.fully_containsx(ymax)
     
     def fully_overlaps(self, other):
         return self.fully_overlapsx(other) and \
             self.fully_overlapsy(other)
 
+    def transformed(self, transform):
+        return Bbox(transform.transform(self.get_points()))
+
+    def inverse_transformed(self, transform):
+        return Bbox(transform.inverted().transform(self.get_points()))
     
+    
 class Bbox(BboxBase):
     def __init__(self, points):
         BboxBase.__init__(self)
         self._points = npy.asarray(points, npy.float_)
-        
+
     [EMAIL PROTECTED]
     def unit():
         return Bbox.from_lbrt(0., 0., 1., 1.)
@@ -198,12 +231,6 @@
         return Bbox(points)
     from_lbrt = staticmethod(from_lbrt)
     
-    def __cmp__(self, other):
-        # MGDTODO: Totally suboptimal
-        if isinstance(other, Bbox) and (self._points == other._points).all():
-            return 0
-        return -1
-
     def __repr__(self):
         return 'Bbox(%s)' % repr(self._points)
     __str__ = __repr__
@@ -219,8 +246,7 @@
                 [max(x.max(), self.xmax), max(y.max(), self.ymax)]],
                 npy.float_)
         self.invalidate()
-
-    # MGDTODO: Probably a more efficient ways to do this...
+        
     def _set_xmin(self, val):
         self._points[0, 0] = val
         self.invalidate()
@@ -278,12 +304,6 @@
         self._points = other.get_points()
         self.invalidate()
         
-    def transformed(self, transform):
-        return Bbox(transform.transform(self._points))
-
-    def inverse_transformed(self, transform):
-        return Bbox(transform.inverted().transform(self._points))
-    
     def expanded(self, sw, sh):
         width = self.width
         height = self.height
@@ -324,6 +344,8 @@
     def __init__(self, bbox, transform):
         assert bbox.is_bbox()
         assert isinstance(transform, Transform)
+        assert transform.input_dims == 2
+        assert transform.output_dims == 2
 
         BboxBase.__init__(self)
         self.bbox = bbox
@@ -335,7 +357,7 @@
         return "TransformedBbox(%s, %s)" % (self.bbox, self.transform)
     __str__ = __repr__
     
-    def _do_invalidation(self):
+    def _do_invalidation(self, which_child, affine_only):
         self._points = None
 
     def get_points(self):
@@ -347,13 +369,10 @@
 class Transform(TransformNode):
     def __init__(self):
         TransformNode.__init__(self)
-    
-    def transform(self, points):
-        raise NotImplementedError()
 
-    def transform_without_affine(self, points):
-        return self.transform(points), IDENTITY
-    
+    def is_separable(self):
+        return False
+        
     def __add__(self, other):
         if isinstance(other, Transform):
             return composite_transform_factory(self, other)
@@ -366,39 +385,69 @@
         raise TypeError(
             "Can not add Transform to object of type '%s'" % type(other))
 
+    def transform(self, points):
+        raise NotImplementedError
+
+    def transform_affine(self, points):
+        raise NotImplementedError
+
+    def transform_non_affine(self, points):
+        raise NotImplementedError
+
+    def get_affine(self):
+        raise NotImplementedError
+    
     def transform_point(self, point):
         return self.transform(npy.asarray([point]))[0]
-    
+
     def has_inverse(self):
         raise NotImplementedError()
     
     def inverted(self):
         raise NotImplementedError()
 
-    def is_separable(self):
-        return False
 
+class TransformWrapper(Transform):
+    def __init__(self, child):
+        assert isinstance(child, Transform)
+        
+        Transform.__init__(self)
+        self.input_dims = child.input_dims
+        self.output_dims = child.output_dims
+        self._child = child
+        self.set_children(['_child'])
 
-class TransformWrapper(Transform):
-    input_dims = 2
-    output_dims = 2
-    
+    def __repr__(self):
+        return "TransformWrapper(%r)" % self._child
+    __str__ = __repr__
+        
     def set(self, child):
-        self.child = child
-        self.child._parents.add(self)
+        assert child.input_dims == self.input_dims
+        assert child.output_dims == self.output_dims
+        self._child = child
+        self.set_children(['_child'])
         self.invalidate()
+        
+    def is_separable(self):
+        return self._child.is_separable()
 
+    def is_affine(self):
+        return self._child.is_affine()
+    
     def transform(self, points):
-        return self.child.transform(points)
+        return self._child.transform(points)
 
-    def transform_without_affine(points):
-        return self.child.transform_without_affine(points)
+    def transform_affine(self, points):
+        return self._child.transform_affine(points)
+
+    def transform_non_affine(self, points):
+        return self._child.transform_non_affine(points)
+
+    def get_affine(self):
+        return self._child.get_affine()
     
     def inverted(self):
-        return self.child.inverted()
-
-    def is_separable(self):
-        return self.child.is_separable()
+        return self._child.inverted()
     
     
 class AffineBase(Transform):
@@ -406,10 +455,13 @@
         Transform.__init__(self)
         self._inverted = None
 
+    def is_affine(self):
+        return True
+        
     def __array__(self, *args, **kwargs):
        return self.get_matrix()
        
-    def _do_invalidation(self):
+    def _do_invalidation(self, which_child, affine_only):
         self._inverted = None
 
     [EMAIL PROTECTED]
@@ -425,10 +477,14 @@
     def get_matrix(self):
         raise NotImplementedError()
 
-    def transform_without_affine(self, points):
-        # MGDTODO: Should we copy the points here?  I'd like to avoid it,
-        # if possible
-        return points, self
+    def transform_affine(self, points):
+        return self.transform(points)
+
+    def transform_non_affine(self, points):
+        return points
+
+    def get_affine(self):
+        return self
     
 
 class Affine1DBase(AffineBase):
@@ -437,13 +493,16 @@
 
     def __init__(self):
         AffineBase.__init__(self)
-    
+
+    def is_separable(self):
+        return True
+        
     def __array__(self, *args, **kwargs):
        return self.get_matrix()
-       
+
     def to_values(self):
         mtx = self.get_matrix()
-        return tuple(mtx[0])
+        return mtx[0]
     
     [EMAIL PROTECTED]
     def matrix_from_values(a, b):
@@ -472,9 +531,6 @@
         points = ma.asarray(values, npy.float_)
         return points * mtx[0,0] + mtx[0,1]
 
-    def is_separable(self):
-        return True
-
     def inverted(self):
         if self._inverted is None:
             mtx = self.get_matrix()
@@ -551,9 +607,12 @@
     
 class IntervalTransform(Affine1DBase):
     def __init__(self, bbox, direction):
+        assert direction in ('x', 'y')
+        assert bbox.is_bbox()
+        
         Affine1DBase.__init__(self)
         self._bbox = bbox
-        self._direction = direction
+        self._direction = "interval" + direction
         self.set_children(['_bbox'])
         self._mtx = None
         
@@ -561,10 +620,9 @@
         return "IntervalTransform(%s)" % (getattr(self._bbox, self._direction))
     __str__ = __repr__
 
-    def _do_invalidation(self):
-        print "IntervalTransform.invalidation", self._bbox
+    def _do_invalidation(self, which_child, affine_only):
         self._mtx = None
-        Affine1DBase._do_invalidation(self)
+        Affine1DBase._do_invalidation(self, which_child, affine_only)
 
     def get_matrix(self):
         if self._mtx is None:
@@ -581,6 +639,10 @@
     def __init__(self):
         AffineBase.__init__(self)
 
+    def is_separable(self):
+        mtx = self.get_matrix()
+        return mtx[0, 1] == 0.0 and mtx[1, 0] == 0.0
+        
     def __array__(self, *args, **kwargs):
        return self.get_matrix()
     
@@ -627,10 +689,6 @@
             mtx = self.get_matrix()
             self._inverted = Affine2D(inv(mtx))
         return self._inverted
-    
-    def is_separable(self):
-        mtx = self.get_matrix()
-        return mtx[0, 1] == 0.0 and mtx[1, 0] == 0.0
 
         
 class Affine2D(Affine2DBase):
@@ -728,6 +786,10 @@
     """
     _mtx = npy.identity(3)
 
+    def __repr__(self):
+        return "IdentityTransform()"
+    __str__ = __repr__
+    
     def __cmp__(self, other):
         if (isinstance(other, Affine2D) and
             (other == IDENTITY)):
@@ -735,34 +797,44 @@
         return -1
 
     def get_matrix(self):
-        return _mtx
+        return self._mtx
     
     def transform(self, points):
         return points
 
-    def transform_without_affine(self, points):
-        return points, self
+    def transform_affine(self, points):
+        return points
 
+    def transform_non_affine(self, points):
+        return points
+
+    def get_affine(self):
+        return self
+    
     def inverted(self):
         return self
+
     
-IDENTITY = Affine2D()
-    
 class BlendedGenericTransform(Transform):
     input_dims = 2
     output_dims = 2
 
     def __init__(self, x_transform, y_transform):
        # Here we ask: "Does it blend?"
-        # MGDTODO: Turn these checks back on
-        # assert x_transform.is_separable()
-        # assert y_transform.is_separable()
+        assert x_transform.is_separable()
+        assert y_transform.is_separable()
         
         Transform.__init__(self)
         self._x = x_transform
         self._y = y_transform
         self.set_children(['_x', '_y'])
 
+    def is_affine(self):
+        return self._x.is_affine() and self._y.is_affine()
+        
+    def is_separable(self):
+        return True
+        
     def __repr__(self):
         return "BlendedGenericTransform(%s,%s)" % (self._x, self._y)
     __str__ = __repr__
@@ -787,33 +859,17 @@
 
         return ma.concatenate((x_points, y_points), 1)
 
-    def transform_without_affine(self, points):
-        x = self._x
-        y = self._y
-        if x == y and x.input_dims == 2:
-            return self._x.transform_without_affine(points)
-
-        if x.input_dims == 2:
-            x_points, x_affine = x.transform_without_affine(points)
-            x_points = x_points[:, 0:1]
-        else:
-            x_points, x_affine = x.transform_without_affine(points[:, 0])
-            x_points = x_points.reshape((len(x_points), 1))
-            
-        if y.input_dims == 2:
-            y_points, y_affine = y.transform_without_affine(points)
-            y_points = y_points[:, 1:]
-        else:
-            y_points, y_affine = y.transform_without_affine(points[:, 1])
-            y_points = y_points.reshape((len(y_points), 1))
-
-        return ma.concatenate((x_points, y_points), 1), 
blended_transform_factory(x_affine, y_affine)
+    def transform_affine(self, points):
+        return points
+        
+    def transform_non_affine(self, points):
+        return self.transform(points)
+        
+    def get_affine(self):
+        return IdentityTransform()
     
     def inverted(self):
         return BlendedGenericTransform(self._x.inverted(), self._y.inverted())
-    
-    def is_separable(self):
-        return True
 
 
 class BlendedAffine1D(Affine2DBase, Transform):
@@ -829,17 +885,17 @@
         Affine2DBase.__init__(self)
         self._mtx = None
 
+    def is_separable(self):
+        return True
+        
     def __repr__(self):
         return "BlendedAffine1D(%s,%s)" % (self._x, self._y)
     __str__ = __repr__
         
-    def _do_invalidation(self):
+    def _do_invalidation(self, which_child, affine_only):
         self._mtx = None
-        Affine2DBase._do_invalidation(self)
+        Affine2DBase._do_invalidation(self, which_child, affine_only)
 
-    def is_separable(self):
-        return True
-
     def get_matrix(self):
         if self._mtx is None:
             x_mtx = self._x.get_matrix()
@@ -854,9 +910,9 @@
     def __init__(self, x_transform, y_transform):
         assert x_transform.is_affine()
         assert y_transform.is_affine()
-        # MGDTODO: Turn these checks back on
-        # assert x_transform.is_separable()
-        # assert y_transform.is_separable()
+        assert x_transform.is_separable()
+        assert y_transform.is_separable()
+
         Transform.__init__(self)
         self._x = x_transform
         self._y = y_transform
@@ -865,17 +921,17 @@
         Affine2DBase.__init__(self)
         self._mtx = None
 
+    def is_separable(self):
+        return True
+        
     def __repr__(self):
         return "BlendedAffine2D(%s,%s)" % (self._x, self._y)
     __str__ = __repr__
         
-    def _do_invalidation(self):
+    def _do_invalidation(self, which_child, affine_only):
         self._mtx = None
-        Affine2DBase._do_invalidation(self)
+        Affine2DBase._do_invalidation(self, which_child, affine_only)
 
-    def is_separable(self):
-        return True
-
     def get_matrix(self):
         if self._mtx is None:
             if self._x == self._y:
@@ -909,8 +965,12 @@
         self._b = b
         self.set_children(['_a', '_b'])
 
-        self.take_shortcut = b.is_affine()
-
+    def is_affine(self):
+        return self._a.is_affine() and self._b.is_affine()
+        
+    def is_separable(self):
+        return self._a.is_separable() and self._b.is_separable()
+        
     def __repr__(self):
         return "CompositeGenericTransform(%s, %s)" % (self._a, self._b)
     __str__ = __repr__
@@ -918,20 +978,24 @@
     def transform(self, points):
         return self._b.transform(self._a.transform(points))
 
-    def transform_without_affine(self, points):
-        if self.take_shortcut:
-            return self._a.transform(points), self._b
-        return self.transform(points), IDENTITY
+    def transform_affine(self, points):
+        return self._b.transform_affine(self._a.transform_affine(points))
+
+    def transform_non_affine(self, points):
+        return 
self._b.transform_non_affine(self._a.transform_non_affine(points))
+
+    def get_affine(self):
+        return self._a.get_affine() + self._b.get_affine()
     
     def inverted(self):
         return CompositeGenericTransform(self._b.inverted(), 
self._a.inverted())
-    
-    def is_separable(self):
-        return self._a.is_separable() and self._b.is_separable()
 
     
 class CompositeAffine2D(Affine2DBase):
     def __init__(self, a, b):
+        assert a.output_dims == b.input_dims
+        self.input_dims = a.input_dims
+        self.output_dims = b.output_dims
         assert a.is_affine()
         assert b.is_affine()
 
@@ -945,9 +1009,9 @@
         return "CompositeAffine2D(%s, %s)" % (self._a, self._b)
     __str__ = __repr__
 
-    def _do_invalidation(self):
+    def _do_invalidation(self, which_child, affine_only):
         self._mtx = None
-        Affine2DBase._do_invalidation(self)
+        Affine2DBase._do_invalidation(self, which_child, affine_only)
     
     def get_matrix(self):
         if self._mtx is None:
@@ -958,7 +1022,9 @@
 
     
 def composite_transform_factory(a, b):
-    if a.is_affine() and b.is_affine():
+    if isinstance(a, BboxTransform) and isinstance(b, BboxTransform):
+        return BboxTransform(a._boxin, b._boxout)
+    if isinstance(a, AffineBase) and isinstance(b, AffineBase):
         return CompositeAffine2D(a, b)
     return CompositeGenericTransform(a, b)
 
@@ -972,33 +1038,6 @@
         return npy.log10(m)
 
 
-class TestLogTransform(Transform):
-    input_dims = 1
-    output_dims = 1
-    def transform(self, a):
-        marray = ma.masked_where(a <= 0.0, a * 10.0)
-        return (npy.log10(marray) * 0.5) + 0.5
-        
-    def inverted(self):
-        return TestInvertLogTransform()
-
-    def is_separable(self):
-        return True
-    
-
-class TestInvertLogTransform(Transform):
-    input_dims = 1
-    output_dims = 1
-    def transform(self, a):
-        return ma.power(10, (a - 0.5) * 2.0) / 10.0
-        
-    def inverted(self):
-        return TestLogTransform()
-
-    def is_separable(self):
-        return True
-
-
 class TestPolarTransform(Transform):
     input_dims = 2
     output_dims = 2
@@ -1078,9 +1117,9 @@
         return "BboxTransform(%s, %s)" % (self._boxin, self._boxout)
     __str__ = __repr__
         
-    def _do_invalidation(self):
+    def _do_invalidation(self, which_child, affine_only):
         self._mtx = None
-        Affine2DBase._do_invalidation(self)
+        Affine2DBase._do_invalidation(self, which_child, affine_only)
 
     def is_separable(self):
         return True
@@ -1101,7 +1140,38 @@
             self._mtx = affine._mtx
         return self._mtx
 
+
+class TransformedPath(TransformNode):
+    def __init__(self, path, transform):
+        assert isinstance(transform, Transform)
+        TransformNode.__init__(self)
+        
+        self._path = path
+        self._transform = transform
+        self.set_children(['_transform'])
+        self._transformed_path = None
+        
+    def _do_invalidation(self, which_child, affine_only):
+        if not (affine_only[0].is_affine() or affine_only[0].is_bbox()):
+            self._transformed_path = None
+                
+    def get_path_and_affine(self):
+        if self._transformed_path is None:
+            vertices = 
self._transform.transform_non_affine(self._path.vertices)
+            self._transformed_path = Path(vertices, self._path.codes)
+        return self._transformed_path, self._transform.get_affine()
+
+    def get_path(self):
+        if self._transformed_path is None:
+            vertices = self._tranform.transform_non_affine(self._path.vertices)
+            self._transformed_path = Path(vertices, self._path.codes)
+        vertices = 
self._transform.transform_affine(self._transformed_path.vertices)
+        return Path(vertices, self._transformed_path.codes)
+
+    def get_affine(self):
+        return self._transform.get_affine()
     
+    
 def nonsingular(vmin, vmax, expander=0.001, tiny=1e-15, increasing=True):
     '''
     Ensure the endpoints of a range are not too close together.
@@ -1128,6 +1198,7 @@
         vmin, vmax = vmax, vmin
     return vmin, vmax
 
+
 # MGDTODO: Optimize (perhaps in an extension)
 def interval_contains(interval, val):
     return interval[0] <= val and interval[1] >= val
@@ -1173,8 +1244,8 @@
     bbox = Bbox.from_lbwh(10, 11, 12, 13)
     assert bbox.bounds == (10, 11, 12, 13)
 
-    bbox_copy = copy.copy(bbox)
-    assert bbox == bbox_copy
+    bbox_copy = copy.deepcopy(bbox)
+    assert (bbox.lbrt == bbox_copy.lbrt).all()
     bbox_copy.max = (14, 15)
     assert bbox.bounds == (10, 11, 12, 13)
     assert bbox_copy.bounds == (10, 11, 4, 4)
@@ -1183,7 +1254,7 @@
     bbox2 = Bbox([[30., 35.], [40., 45.]])
     trans = BboxTransform(bbox1, bbox2)
     bbox3 = bbox1.transformed(trans)
-    assert bbox3 == bbox2
+    assert (bbox3.lbrt == bbox2.lbrt).all()
 
     translation = Affine2D().translate(10, 20)
     assert translation.to_values() == (1, 0, 0, 1, 10, 20)
@@ -1210,12 +1281,6 @@
 
     print points
     
-    comp = TestLogTransform() + Affine2D().rotate_deg(15)
-    tpoints = comp.transform(points)
-    itpoints = comp.inverted().transform(tpoints)
-    print tpoints, itpoints
-    assert (points.round() == itpoints.round()).all()
-    
     # Here are some timing tests
     points = npy.asarray([(random(), random()) for i in xrange(10000)])
     t = timeit.Timer("trans_sum.transform(points)", "from __main__ import 
trans_sum, points")


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

Reply via email to