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