From: <md...@us...> - 2009-05-22 14:01:23
|
Revision: 7131 http://matplotlib.svn.sourceforge.net/matplotlib/?rev=7131&view=rev Author: mdboom Date: 2009-05-22 14:00:12 +0000 (Fri, 22 May 2009) Log Message: ----------- Fix problem with polar grid lines by specifying the number of interpolation steps on a per-Path basis. This isn't really a public API -- it is intended for internal use only. Modified Paths: -------------- trunk/matplotlib/doc/api/api_changes.rst trunk/matplotlib/examples/api/custom_projection_example.py trunk/matplotlib/examples/pylab_examples/polar_bar.py trunk/matplotlib/lib/matplotlib/axis.py trunk/matplotlib/lib/matplotlib/cbook.py trunk/matplotlib/lib/matplotlib/lines.py trunk/matplotlib/lib/matplotlib/path.py trunk/matplotlib/lib/matplotlib/projections/polar.py trunk/matplotlib/lib/matplotlib/transforms.py Modified: trunk/matplotlib/doc/api/api_changes.rst =================================================================== --- trunk/matplotlib/doc/api/api_changes.rst 2009-05-21 21:06:49 UTC (rev 7130) +++ trunk/matplotlib/doc/api/api_changes.rst 2009-05-22 14:00:12 UTC (rev 7131) @@ -17,6 +17,14 @@ .. _configobj: http://www.voidspace.org.uk/python/configobj.html .. _`enthought.traits`: http://code.enthought.com/projects/traits +Changes beyond 0.98.x +===================== + +* Polar plots no longer accept a resolution kwarg. Instead, each Path + must specify its own number of interpolation steps. This is + unlikely to be a user-visible change -- if interpolation of data is + required, that should be done before passing it to matplotlib. + Changes for 0.98.x ================== * psd(), csd(), and cohere() will now automatically wrap negative Modified: trunk/matplotlib/examples/api/custom_projection_example.py =================================================================== --- trunk/matplotlib/examples/api/custom_projection_example.py 2009-05-21 21:06:49 UTC (rev 7130) +++ trunk/matplotlib/examples/api/custom_projection_example.py 2009-05-22 14:00:12 UTC (rev 7131) @@ -373,15 +373,6 @@ output_dims = 2 is_separable = False - def __init__(self, resolution): - """ - Create a new Hammer transform. Resolution is the number of steps - to interpolate between each input line segment to approximate its - path in curved Hammer space. - """ - Transform.__init__(self) - self._resolution = resolution - def transform(self, ll): """ Override the transform method to implement the custom transform. @@ -410,11 +401,11 @@ # ``transform_path``. def transform_path(self, path): vertices = path.vertices - ipath = path.interpolated(self._resolution) + ipath = path.interpolated(path._interpolation_steps) return Path(self.transform(ipath.vertices), ipath.codes) def inverted(self): - return HammerAxes.InvertedHammerTransform(self._resolution) + return HammerAxes.InvertedHammerTransform() inverted.__doc__ = Transform.inverted.__doc__ class InvertedHammerTransform(Transform): @@ -422,10 +413,6 @@ output_dims = 2 is_separable = False - def __init__(self, resolution): - Transform.__init__(self) - self._resolution = resolution - def transform(self, xy): x = xy[:, 0:1] y = xy[:, 1:2] @@ -440,7 +427,7 @@ def inverted(self): # The inverse of the inverse is the original transform... ;) - return HammerAxes.HammerTransform(self._resolution) + return HammerAxes.HammerTransform() inverted.__doc__ = Transform.inverted.__doc__ # Now register the projection with matplotlib so the user can select Modified: trunk/matplotlib/examples/pylab_examples/polar_bar.py =================================================================== --- trunk/matplotlib/examples/pylab_examples/polar_bar.py 2009-05-21 21:06:49 UTC (rev 7130) +++ trunk/matplotlib/examples/pylab_examples/polar_bar.py 2009-05-22 14:00:12 UTC (rev 7131) @@ -7,7 +7,7 @@ # force square figure and square axes looks better for polar, IMO fig = figure(figsize=(8,8)) -ax = fig.add_axes([0.1, 0.1, 0.8, 0.8], polar=True, resolution=50) +ax = fig.add_axes([0.1, 0.1, 0.8, 0.8], polar=True) N = 20 theta = np.arange(0.0, 2*np.pi, 2*np.pi/N) Modified: trunk/matplotlib/lib/matplotlib/axis.py =================================================================== --- trunk/matplotlib/lib/matplotlib/axis.py 2009-05-21 21:06:49 UTC (rev 7130) +++ trunk/matplotlib/lib/matplotlib/axis.py 2009-05-22 14:00:12 UTC (rev 7131) @@ -16,6 +16,7 @@ import matplotlib.transforms as mtransforms import matplotlib.units as munits +GRIDLINE_INTERPOLATION_STEPS = 180 class Tick(artist.Artist): """ @@ -308,6 +309,7 @@ linewidth=rcParams['grid.linewidth'], ) l.set_transform(self.axes.get_xaxis_transform()) + l.get_path()._interpolation_steps = GRIDLINE_INTERPOLATION_STEPS self._set_artist_props(l) return l @@ -437,6 +439,7 @@ ) l.set_transform(self.axes.get_yaxis_transform()) + l.get_path()._interpolation_steps = GRIDLINE_INTERPOLATION_STEPS self._set_artist_props(l) return l Modified: trunk/matplotlib/lib/matplotlib/cbook.py =================================================================== --- trunk/matplotlib/lib/matplotlib/cbook.py 2009-05-21 21:06:49 UTC (rev 7130) +++ trunk/matplotlib/lib/matplotlib/cbook.py 2009-05-22 14:00:12 UTC (rev 7131) @@ -1177,6 +1177,9 @@ def simple_linear_interpolation(a, steps): + if steps == 1: + return a + steps = np.floor(steps) new_length = ((len(a) - 1) * steps) + 1 new_shape = list(a.shape) Modified: trunk/matplotlib/lib/matplotlib/lines.py =================================================================== --- trunk/matplotlib/lib/matplotlib/lines.py 2009-05-21 21:06:49 UTC (rev 7130) +++ trunk/matplotlib/lib/matplotlib/lines.py 2009-05-22 14:00:12 UTC (rev 7131) @@ -443,7 +443,11 @@ self._subslice = False if len(x) > 100 and self._is_sorted(x): self._subslice = True - self._path = Path(self._xy) + if hasattr(self, '_path'): + interpolation_steps = self._path._interpolation_steps + else: + interpolation_steps = 1 + self._path = Path(self._xy, None, interpolation_steps) self._transformed_path = None self._invalid = False Modified: trunk/matplotlib/lib/matplotlib/path.py =================================================================== --- trunk/matplotlib/lib/matplotlib/path.py 2009-05-21 21:06:49 UTC (rev 7130) +++ trunk/matplotlib/lib/matplotlib/path.py 2009-05-22 14:00:12 UTC (rev 7131) @@ -80,7 +80,7 @@ code_type = np.uint8 - def __init__(self, vertices, codes=None): + def __init__(self, vertices, codes=None, _interpolation_steps=1): """ Create a new path with the given vertices and codes. @@ -100,6 +100,11 @@ to NaNs which are then handled correctly by the Agg PathIterator and other consumers of path data, such as :meth:`iter_segments`. + + *interpolation_steps* is used as a hint to certain projections, + such as Polar, that this path should be linearly interpolated + immediately before drawing. This attribute is primarily an + implementation detail and is not intended for public use. """ if ma.isMaskedArray(vertices): vertices = vertices.astype(np.float_).filled(np.nan) @@ -118,12 +123,10 @@ (len(vertices) >= 128 and (codes is None or np.all(codes <= Path.LINETO)))) self.simplify_threshold = rcParams['path.simplify_threshold'] - # The following operation takes most of the time in this - # initialization, and it does not appear to be used anywhere; - # if it is occasionally needed, it could be made a property. - #self.has_nonfinite = not np.isfinite(vertices).all() + self.has_nonfinite = not np.isfinite(vertices).all() self.codes = codes self.vertices = vertices + self._interpolation_steps = _interpolation_steps @classmethod def make_compound_path(cls, *args): @@ -224,7 +227,8 @@ transformed result and automatically update when the transform changes. """ - return Path(transform.transform(self.vertices), self.codes) + return Path(transform.transform(self.vertices), self.codes, + self._interpolation_steps) def contains_point(self, point, transform=None): """ @@ -292,6 +296,9 @@ Returns a new path resampled to length N x steps. Does not currently handle interpolating curves. """ + if steps == 1: + return self + vertices = simple_linear_interpolation(self.vertices, steps) codes = self.codes if codes is not None: Modified: trunk/matplotlib/lib/matplotlib/projections/polar.py =================================================================== --- trunk/matplotlib/lib/matplotlib/projections/polar.py 2009-05-21 21:06:49 UTC (rev 7130) +++ trunk/matplotlib/lib/matplotlib/projections/polar.py 2009-05-22 14:00:12 UTC (rev 7131) @@ -1,4 +1,5 @@ import math +import warnings import numpy as npy @@ -32,15 +33,6 @@ output_dims = 2 is_separable = False - def __init__(self, resolution): - """ - Create a new polar transform. Resolution is the number of steps - to interpolate between each input line segment to approximate its - path in curved polar space. - """ - Transform.__init__(self) - self._resolution = resolution - def transform(self, tr): xy = npy.zeros(tr.shape, npy.float_) t = tr[:, 0:1] @@ -59,7 +51,7 @@ vertices = path.vertices if len(vertices) == 2 and vertices[0, 0] == vertices[1, 0]: return Path(self.transform(vertices), path.codes) - ipath = path.interpolated(self._resolution) + ipath = path.interpolated(path._interpolation_steps) return Path(self.transform(ipath.vertices), ipath.codes) transform_path.__doc__ = Transform.transform_path.__doc__ @@ -67,7 +59,7 @@ transform_path_non_affine.__doc__ = Transform.transform_path_non_affine.__doc__ def inverted(self): - return PolarAxes.InvertedPolarTransform(self._resolution) + return PolarAxes.InvertedPolarTransform() inverted.__doc__ = Transform.inverted.__doc__ class PolarAffine(Affine2DBase): @@ -109,10 +101,6 @@ output_dims = 2 is_separable = False - def __init__(self, resolution): - Transform.__init__(self) - self._resolution = resolution - def transform(self, xy): x = xy[:, 0:1] y = xy[:, 1:] @@ -123,7 +111,7 @@ transform.__doc__ = Transform.transform.__doc__ def inverted(self): - return PolarAxes.PolarTransform(self._resolution) + return PolarAxes.PolarTransform() inverted.__doc__ = Transform.inverted.__doc__ class ThetaFormatter(Formatter): @@ -177,8 +165,6 @@ return 0, vmax - RESOLUTION = 1 - def __init__(self, *args, **kwargs): """ Create a new Polar Axes for a polar plot. @@ -192,8 +178,11 @@ self._rpad = 0.05 self.resolution = kwargs.pop('resolution', None) - if self.resolution is None: - self.resolution = self.RESOLUTION + if self.resolution not in (None, 1): + warnings.warn( + """The resolution kwarg to Polar plots is now ignored. +If you need to interpolate data points, consider running +cbook.simple_linear_interpolation on the data before passing to matplotlib.""") Axes.__init__(self, *args, **kwargs) self.set_aspect('equal', adjustable='box', anchor='C') self.cla() @@ -221,7 +210,7 @@ self.transScale = TransformWrapper(IdentityTransform()) # A (possibly non-linear) projection on the (already scaled) data - self.transProjection = self.PolarTransform(self.resolution) + self.transProjection = self.PolarTransform() # An affine transformation on the data, generally to limit the # range of the axes Modified: trunk/matplotlib/lib/matplotlib/transforms.py =================================================================== --- trunk/matplotlib/lib/matplotlib/transforms.py 2009-05-21 21:06:49 UTC (rev 7130) +++ trunk/matplotlib/lib/matplotlib/transforms.py 2009-05-22 14:00:12 UTC (rev 7131) @@ -1119,7 +1119,8 @@ In some cases, this transform may insert curves into the path that began as line segments. """ - return Path(self.transform(path.vertices), path.codes) + return Path(self.transform(path.vertices), path.codes, + path._interpolation_steps) def transform_path_affine(self, path): """ @@ -1143,7 +1144,8 @@ ``transform_path(path)`` is equivalent to ``transform_path_affine(transform_path_non_affine(values))``. """ - return Path(self.transform_non_affine(path.vertices), path.codes) + return Path(self.transform_non_affine(path.vertices), path.codes, + self._interpolation_steps) def transform_angles(self, angles, pts, radians=False, pushoff=1e-5): """ @@ -2181,7 +2183,8 @@ self._transformed_path = \ self._transform.transform_path_non_affine(self._path) self._transformed_points = \ - Path(self._transform.transform_non_affine(self._path.vertices)) + Path(self._transform.transform_non_affine(self._path.vertices), + None, self._path._interpolation_steps) self._invalid = 0 def get_transformed_points_and_affine(self): This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |