Revision: 7170
          http://matplotlib.svn.sourceforge.net/matplotlib/?rev=7170&view=rev
Author:   astraw
Date:     2009-06-01 21:41:46 +0000 (Mon, 01 Jun 2009)

Log Message:
-----------
Spine is now derived from Patch

Modified Paths:
--------------
    trunk/matplotlib/CHANGELOG
    trunk/matplotlib/examples/api/custom_projection_example.py
    trunk/matplotlib/examples/pylab_examples/spine_placement_demo.py
    trunk/matplotlib/lib/matplotlib/axes.py
    trunk/matplotlib/lib/matplotlib/projections/geo.py
    trunk/matplotlib/lib/matplotlib/projections/polar.py
    trunk/matplotlib/lib/matplotlib/spines.py

Modified: trunk/matplotlib/CHANGELOG
===================================================================
--- trunk/matplotlib/CHANGELOG  2009-06-01 21:41:31 UTC (rev 7169)
+++ trunk/matplotlib/CHANGELOG  2009-06-01 21:41:46 UTC (rev 7170)
@@ -1,3 +1,5 @@
+2009-06-01 Spine is now derived from Patch - ADS
+
 2009-06-01 use cbook.is_string_like() instead of isinstance() for spines - ADS
 
 2009-06-01 cla() support for spines - ADS

Modified: trunk/matplotlib/examples/api/custom_projection_example.py
===================================================================
--- trunk/matplotlib/examples/api/custom_projection_example.py  2009-06-01 
21:41:31 UTC (rev 7169)
+++ trunk/matplotlib/examples/api/custom_projection_example.py  2009-06-01 
21:41:46 UTC (rev 7170)
@@ -237,7 +237,8 @@
         return Circle((0.5, 0.5), 0.5)
 
     def _gen_axes_spines(self):
-        return {'hammer':mspines.Spine(self,'hammer',Circle((0.5, 0.5), 0.5))}
+        return {'hammer':mspines.Spine.circular_spine(self,
+                                                      (0.5, 0.5), 0.5)}
 
     # Prevent the user from applying scales to one or both of the
     # axes.  In this particular case, scaling the axes wouldn't make

Modified: trunk/matplotlib/examples/pylab_examples/spine_placement_demo.py
===================================================================
--- trunk/matplotlib/examples/pylab_examples/spine_placement_demo.py    
2009-06-01 21:41:31 UTC (rev 7169)
+++ trunk/matplotlib/examples/pylab_examples/spine_placement_demo.py    
2009-06-01 21:41:46 UTC (rev 7170)
@@ -12,7 +12,7 @@
     if loc in ['left','bottom']:
         spine.set_position(('outward',10)) # outward by 10 points
     elif loc in ['right','top']:
-        spine.set_color('none') # don't draw spine
+        spine.set_edgecolor('none') # don't draw spine
     else:
         raise ValueError('unknown spine location: %s'%loc)
 
@@ -34,9 +34,9 @@
 ax.set_title('centered spines')
 ax.plot(x,y)
 ax.spines['left'].set_position('center')
-ax.spines['right'].set_color('none')
+ax.spines['right'].set_edgecolor('none')
 ax.spines['bottom'].set_position('center')
-ax.spines['top'].set_color('none')
+ax.spines['top'].set_edgecolor('none')
 ax.xaxis.set_ticks_position('bottom')
 ax.yaxis.set_ticks_position('left')
 
@@ -44,9 +44,9 @@
 ax.set_title('zeroed spines')
 ax.plot(x,y)
 ax.spines['left'].set_position('zero')
-ax.spines['right'].set_color('none')
+ax.spines['right'].set_edgecolor('none')
 ax.spines['bottom'].set_position('zero')
-ax.spines['top'].set_color('none')
+ax.spines['top'].set_edgecolor('none')
 ax.xaxis.set_ticks_position('bottom')
 ax.yaxis.set_ticks_position('left')
 
@@ -54,9 +54,9 @@
 ax.set_title('spines at axes (0.6, 0.1)')
 ax.plot(x,y)
 ax.spines['left'].set_position(('axes',0.6))
-ax.spines['right'].set_color('none')
+ax.spines['right'].set_edgecolor('none')
 ax.spines['bottom'].set_position(('axes',0.1))
-ax.spines['top'].set_color('none')
+ax.spines['top'].set_edgecolor('none')
 ax.xaxis.set_ticks_position('bottom')
 ax.yaxis.set_ticks_position('left')
 
@@ -64,9 +64,9 @@
 ax.set_title('spines at data (1,2)')
 ax.plot(x,y)
 ax.spines['left'].set_position(('data',1))
-ax.spines['right'].set_color('none')
+ax.spines['right'].set_edgecolor('none')
 ax.spines['bottom'].set_position(('data',2))
-ax.spines['top'].set_color('none')
+ax.spines['top'].set_edgecolor('none')
 ax.xaxis.set_ticks_position('bottom')
 ax.yaxis.set_ticks_position('left')
 
@@ -77,7 +77,7 @@
         if loc in spines:
             spine.set_position(('outward',10)) # outward by 10 points
         else:
-            spine.set_color('none') # don't draw spine
+            spine.set_edgecolor('none') # don't draw spine
 
     # turn off ticks where there is no spine
     if 'left' in spines:

Modified: trunk/matplotlib/lib/matplotlib/axes.py
===================================================================
--- trunk/matplotlib/lib/matplotlib/axes.py     2009-06-01 21:41:31 UTC (rev 
7169)
+++ trunk/matplotlib/lib/matplotlib/axes.py     2009-06-01 21:41:46 UTC (rev 
7170)
@@ -891,14 +891,10 @@
             Intended to be overridden by new projection types.
         """
         return {
-            'left':mspines.Spine(self,'left',
-                                 mlines.Line2D((0.0, 0.0), (0.0, 1.0))),
-            'right':mspines.Spine(self,'right',
-                                  mlines.Line2D((1.0, 1.0), (0.0, 1.0))),
-            'bottom':mspines.Spine(self,'bottom',
-                                   mlines.Line2D((0.0, 1.0), (0.0, 0.0))),
-            'top':mspines.Spine(self,'top',
-                                mlines.Line2D((0.0, 1.0), (1.0, 1.0))),
+            'left':mspines.Spine.linear_spine(self,'left'),
+            'right':mspines.Spine.linear_spine(self,'right'),
+            'bottom':mspines.Spine.linear_spine(self,'bottom'),
+            'top':mspines.Spine.linear_spine(self,'top'),
             }
 
     def cla(self):

Modified: trunk/matplotlib/lib/matplotlib/projections/geo.py
===================================================================
--- trunk/matplotlib/lib/matplotlib/projections/geo.py  2009-06-01 21:41:31 UTC 
(rev 7169)
+++ trunk/matplotlib/lib/matplotlib/projections/geo.py  2009-06-01 21:41:46 UTC 
(rev 7170)
@@ -145,7 +145,8 @@
         return Circle((0.5, 0.5), 0.5)
 
     def _gen_axes_spines(self):
-        return {'geo':mspines.Spine(self,'geo',Circle((0.5, 0.5), 0.5))}
+        return {'geo':mspines.Spine.circular_spine(self,
+                                                   (0.5, 0.5), 0.5)}
 
     def set_yscale(self, *args, **kwargs):
         if args[0] != 'linear':

Modified: trunk/matplotlib/lib/matplotlib/projections/polar.py
===================================================================
--- trunk/matplotlib/lib/matplotlib/projections/polar.py        2009-06-01 
21:41:31 UTC (rev 7169)
+++ trunk/matplotlib/lib/matplotlib/projections/polar.py        2009-06-01 
21:41:46 UTC (rev 7170)
@@ -294,7 +294,8 @@
         return Circle((0.5, 0.5), 0.5)
 
     def _gen_axes_spines(self):
-        return {'polar':mspines.Spine(self,'polar',Circle((0.5, 0.5), 0.5))}
+        return {'polar':mspines.Spine.circular_spine(self,
+                                                     (0.5, 0.5), 0.5)}
 
     def set_rmax(self, rmax):
         self.viewLim.y0 = 0

Modified: trunk/matplotlib/lib/matplotlib/spines.py
===================================================================
--- trunk/matplotlib/lib/matplotlib/spines.py   2009-06-01 21:41:31 UTC (rev 
7169)
+++ trunk/matplotlib/lib/matplotlib/spines.py   2009-06-01 21:41:46 UTC (rev 
7170)
@@ -8,10 +8,11 @@
 import matplotlib.transforms as mtransforms
 import matplotlib.lines as mlines
 import matplotlib.patches as mpatches
+import matplotlib.path as mpath
 import matplotlib.cbook as cbook
 import warnings
 
-class Spine(martist.Artist):
+class Spine(mpatches.Patch):
     """an axis spine -- the line noting the data area boundaries
 
     Spines are the lines connecting the axis tick marks and noting the
@@ -20,39 +21,98 @@
     for more information.
 
     The default position is ``('outward',0)``.
+
+    Spines are subclasses of class:`~matplotlib.patches.Patch`, and
+    inherit much of their behavior.
+
+    Spines draw a line or a circle, depending if
+    function:`~matplotlib.spines.Spine.set_patch_line` or
+    function:`~matplotlib.spines.Spine.set_patch_circle` has been
+    called. Line-like is the default.
+
     """
     def __str__(self):
         return "Spine"
 
-    def __init__(self,axes,spine_type,artist):
+    def __init__(self,axes,spine_type,path,**kwargs):
         """
         - *axes* : the Axes instance containing the spine
         - *spine_type* : a string specifying the spine type
-        - *artist* : the artist instance used to draw the spine
+        - *path* : the path instance used to draw the spine
+
+        Valid kwargs are:
+        %(Patch)s
         """
-        martist.Artist.__init__(self)
+        super(Spine,self).__init__(**kwargs)
         self.axes = axes
         self.set_figure(self.axes.figure)
         self.spine_type = spine_type
-        self.artist = artist
-        self.color = rcParams['axes.edgecolor']
+        self.set_facecolor('none')
+        self.set_edgecolor( rcParams['axes.edgecolor'] )
+        self.set_linewidth(rcParams['axes.linewidth'])
         self.axis = None
 
-        if isinstance(self.artist,mlines.Line2D):
-            self.artist.set_color(self.color)
-            self.artist.set_linewidth(rcParams['axes.linewidth'])
-        elif isinstance(self.artist,mpatches.Patch):
-            self.artist.set_facecolor('none')
-            self.artist.set_edgecolor(self.color)
-            self.artist.set_linewidth(rcParams['axes.linewidth'])
-        self.artist.set_zorder(2.5)
-        self.artist.set_transform(self.axes.transAxes) # default transform
+        self.set_zorder(2.5)
+        self.set_transform(self.axes.transAxes) # default transform
 
         # Defer initial position determination. (Not much support for
         # non-rectangular axes is currently implemented, and this lets
         # them pass through the spines machinery without errors.)
         self._position = None
+        assert isinstance(path,matplotlib.path.Path)
+        self._path = path
 
+        # To support drawing both linear and circular spines, this
+        # class implements Patch behavior two ways. If
+        # self._patch_type == 'line', behave like a mpatches.PathPatch
+        # instance. If self._patch_type == 'circle', behave like a
+        # mpatches.Ellipse instance.
+        self._patch_type = 'line'
+
+        # Behavior copied from mpatches.Ellipse:
+        # Note: This cannot be calculated until this is added to an Axes
+        self._patch_transform = mtransforms.IdentityTransform()
+    __init__.__doc__ = cbook.dedent(__init__.__doc__) % martist.kwdocd
+
+    def set_patch_circle(self,center,radius):
+        """set the spine to be circular"""
+        self._patch_type = 'circle'
+        self._center = center
+        self._width = radius*2
+        self._height = radius*2
+        self._angle = 0
+
+    def set_patch_line(self):
+        """set the spine to be linear"""
+        self._patch_type = 'line'
+
+    # Behavior copied from mpatches.Ellipse:
+    def _recompute_transform(self):
+        """NOTE: This cannot be called until after this has been added
+                 to an Axes, otherwise unit conversion will fail. This
+                 maxes it very important to call the accessor method and
+                 not directly access the transformation member variable.
+        """
+        assert self._patch_type == 'circle'
+        center = (self.convert_xunits(self._center[0]),
+                  self.convert_yunits(self._center[1]))
+        width = self.convert_xunits(self._width)
+        height = self.convert_yunits(self._height)
+        self._patch_transform = mtransforms.Affine2D() \
+            .scale(width * 0.5, height * 0.5) \
+            .rotate_deg(self._angle) \
+            .translate(*center)
+
+    def get_patch_transform(self):
+        if self._patch_type == 'circle':
+            self._recompute_transform()
+            return self._patch_transform
+        else:
+            return super(Spine,self).get_patch_transform()
+
+    def get_path(self):
+        return self._path
+
     def _ensure_position_is_set(self):
         if self._position is None:
             # default position
@@ -76,14 +136,6 @@
         if self.axis is not None:
             self.axis.cla()
 
-    @allow_rasterization
-    def draw(self,renderer):
-        "draw everything that belongs to the spine"
-        if self.color=='none':
-            # don't draw invisible spines
-            return
-        self.artist.draw(renderer)
-
     def _calc_offset_transform(self):
         """calculate the offset transform performed by the spine"""
         self._ensure_position_is_set()
@@ -176,7 +228,7 @@
         elif self.spine_type in ['bottom','top']:
             t2 = mtransforms.blended_transform_factory(self.axes.transAxes,
                                                        t)
-        self.artist.set_transform(t2)
+        self.set_transform(t2)
 
         if self.axis is not None:
             self.axis.cla()
@@ -223,17 +275,31 @@
         else:
             raise ValueError("unknown spine_transform type: %s"%what)
 
-    def set_color(self,value):
-        """set the color of the spine artist
+    @classmethod
+    def linear_spine(cls, axes, spine_type, **kwargs):
+        """
+        (staticmethod) Returns a linear :class:`Spine`.
+        """
+        if spine_type=='left':
+            path = mpath.Path([(0.0, 0.0), (0.0, 1.0)])
+        elif spine_type=='right':
+            path = mpath.Path([(1.0, 0.0), (1.0, 1.0)])
+        elif spine_type=='bottom':
+            path = mpath.Path([(0.0, 0.0), (1.0, 0.0)])
+        elif spine_type=='top':
+            path = mpath.Path([(0.0, 1.0), (1.0, 1.0)])
+        else:
+            raise ValueError('unable to make path for spine "%s"'%spine_type)
+        result = cls(axes,spine_type,path,**kwargs)
+        return result
 
-        Note: a value of 'none' will cause the artist not to be drawn.
+    @classmethod
+    def circular_spine(cls,axes,center,radius,**kwargs):
         """
-        self.color = value
-        if isinstance(self.artist,mlines.Line2D):
-            self.artist.set_color(self.color)
-        elif isinstance(self.artist,mpatches.Patch):
-            self.artist.set_edgecolor(self.color)
-
-    def get_color(self):
-        """get the color of the spine artist"""
-        return self.color
+        (staticmethod) Returns a circular :class:`Spine`.
+        """
+        path = mpath.Path.unit_circle()
+        spine_type = 'circle'
+        result = cls(axes,spine_type,path,**kwargs)
+        result.set_patch_circle(center,radius)
+        return result


This was sent by the SourceForge.net collaborative development platform, the 
world's largest Open Source development site.

------------------------------------------------------------------------------
OpenSolaris 2009.06 is a cutting edge operating system for enterprises 
looking to deploy the next generation of Solaris that includes the latest 
innovations from Sun and the OpenSource community. Download a copy and 
enjoy capabilities such as Networking, Storage and Virtualization. 
Go to: http://p.sf.net/sfu/opensolaris-get
_______________________________________________
Matplotlib-checkins mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/matplotlib-checkins

Reply via email to