Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 3093ce9

Browse files
committed
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.
svn path=/trunk/matplotlib/; revision=7131
1 parent d78f889 commit 3093ce9

9 files changed

Lines changed: 52 additions & 48 deletions

File tree

doc/api/api_changes.rst

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,14 @@ list may help describe what changes may be necessary in your code.
1717
.. _configobj: http://www.voidspace.org.uk/python/configobj.html
1818
.. _`enthought.traits`: http://code.enthought.com/projects/traits
1919

20+
Changes beyond 0.98.x
21+
=====================
22+
23+
* Polar plots no longer accept a resolution kwarg. Instead, each Path
24+
must specify its own number of interpolation steps. This is
25+
unlikely to be a user-visible change -- if interpolation of data is
26+
required, that should be done before passing it to matplotlib.
27+
2028
Changes for 0.98.x
2129
==================
2230
* psd(), csd(), and cohere() will now automatically wrap negative

examples/api/custom_projection_example.py

Lines changed: 3 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -373,15 +373,6 @@ class HammerTransform(Transform):
373373
output_dims = 2
374374
is_separable = False
375375

376-
def __init__(self, resolution):
377-
"""
378-
Create a new Hammer transform. Resolution is the number of steps
379-
to interpolate between each input line segment to approximate its
380-
path in curved Hammer space.
381-
"""
382-
Transform.__init__(self)
383-
self._resolution = resolution
384-
385376
def transform(self, ll):
386377
"""
387378
Override the transform method to implement the custom transform.
@@ -410,22 +401,18 @@ def transform(self, ll):
410401
# ``transform_path``.
411402
def transform_path(self, path):
412403
vertices = path.vertices
413-
ipath = path.interpolated(self._resolution)
404+
ipath = path.interpolated(path._interpolation_steps)
414405
return Path(self.transform(ipath.vertices), ipath.codes)
415406

416407
def inverted(self):
417-
return HammerAxes.InvertedHammerTransform(self._resolution)
408+
return HammerAxes.InvertedHammerTransform()
418409
inverted.__doc__ = Transform.inverted.__doc__
419410

420411
class InvertedHammerTransform(Transform):
421412
input_dims = 2
422413
output_dims = 2
423414
is_separable = False
424415

425-
def __init__(self, resolution):
426-
Transform.__init__(self)
427-
self._resolution = resolution
428-
429416
def transform(self, xy):
430417
x = xy[:, 0:1]
431418
y = xy[:, 1:2]
@@ -440,7 +427,7 @@ def transform(self, xy):
440427

441428
def inverted(self):
442429
# The inverse of the inverse is the original transform... ;)
443-
return HammerAxes.HammerTransform(self._resolution)
430+
return HammerAxes.HammerTransform()
444431
inverted.__doc__ = Transform.inverted.__doc__
445432

446433
# Now register the projection with matplotlib so the user can select

examples/pylab_examples/polar_bar.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77

88
# force square figure and square axes looks better for polar, IMO
99
fig = figure(figsize=(8,8))
10-
ax = fig.add_axes([0.1, 0.1, 0.8, 0.8], polar=True, resolution=50)
10+
ax = fig.add_axes([0.1, 0.1, 0.8, 0.8], polar=True)
1111

1212
N = 20
1313
theta = np.arange(0.0, 2*np.pi, 2*np.pi/N)

lib/matplotlib/axis.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
import matplotlib.transforms as mtransforms
1717
import matplotlib.units as munits
1818

19+
GRIDLINE_INTERPOLATION_STEPS = 180
1920

2021
class Tick(artist.Artist):
2122
"""
@@ -308,6 +309,7 @@ def _get_gridline(self):
308309
linewidth=rcParams['grid.linewidth'],
309310
)
310311
l.set_transform(self.axes.get_xaxis_transform())
312+
l.get_path()._interpolation_steps = GRIDLINE_INTERPOLATION_STEPS
311313
self._set_artist_props(l)
312314

313315
return l
@@ -437,6 +439,7 @@ def _get_gridline(self):
437439
)
438440

439441
l.set_transform(self.axes.get_yaxis_transform())
442+
l.get_path()._interpolation_steps = GRIDLINE_INTERPOLATION_STEPS
440443
self._set_artist_props(l)
441444
return l
442445

lib/matplotlib/cbook.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1177,6 +1177,9 @@ def get_siblings(self, a):
11771177

11781178

11791179
def simple_linear_interpolation(a, steps):
1180+
if steps == 1:
1181+
return a
1182+
11801183
steps = np.floor(steps)
11811184
new_length = ((len(a) - 1) * steps) + 1
11821185
new_shape = list(a.shape)

lib/matplotlib/lines.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -443,7 +443,11 @@ def recache(self):
443443
self._subslice = False
444444
if len(x) > 100 and self._is_sorted(x):
445445
self._subslice = True
446-
self._path = Path(self._xy)
446+
if hasattr(self, '_path'):
447+
interpolation_steps = self._path._interpolation_steps
448+
else:
449+
interpolation_steps = 1
450+
self._path = Path(self._xy, None, interpolation_steps)
447451
self._transformed_path = None
448452
self._invalid = False
449453

lib/matplotlib/path.py

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ class Path(object):
8080

8181
code_type = np.uint8
8282

83-
def __init__(self, vertices, codes=None):
83+
def __init__(self, vertices, codes=None, _interpolation_steps=1):
8484
"""
8585
Create a new path with the given vertices and codes.
8686
@@ -100,6 +100,11 @@ def __init__(self, vertices, codes=None):
100100
to NaNs which are then handled correctly by the Agg
101101
PathIterator and other consumers of path data, such as
102102
:meth:`iter_segments`.
103+
104+
*interpolation_steps* is used as a hint to certain projections,
105+
such as Polar, that this path should be linearly interpolated
106+
immediately before drawing. This attribute is primarily an
107+
implementation detail and is not intended for public use.
103108
"""
104109
if ma.isMaskedArray(vertices):
105110
vertices = vertices.astype(np.float_).filled(np.nan)
@@ -118,12 +123,10 @@ def __init__(self, vertices, codes=None):
118123
(len(vertices) >= 128 and
119124
(codes is None or np.all(codes <= Path.LINETO))))
120125
self.simplify_threshold = rcParams['path.simplify_threshold']
121-
# The following operation takes most of the time in this
122-
# initialization, and it does not appear to be used anywhere;
123-
# if it is occasionally needed, it could be made a property.
124-
#self.has_nonfinite = not np.isfinite(vertices).all()
126+
self.has_nonfinite = not np.isfinite(vertices).all()
125127
self.codes = codes
126128
self.vertices = vertices
129+
self._interpolation_steps = _interpolation_steps
127130

128131
@classmethod
129132
def make_compound_path(cls, *args):
@@ -224,7 +227,8 @@ def transformed(self, transform):
224227
transformed result and automatically update when the
225228
transform changes.
226229
"""
227-
return Path(transform.transform(self.vertices), self.codes)
230+
return Path(transform.transform(self.vertices), self.codes,
231+
self._interpolation_steps)
228232

229233
def contains_point(self, point, transform=None):
230234
"""
@@ -292,6 +296,9 @@ def interpolated(self, steps):
292296
Returns a new path resampled to length N x steps. Does not
293297
currently handle interpolating curves.
294298
"""
299+
if steps == 1:
300+
return self
301+
295302
vertices = simple_linear_interpolation(self.vertices, steps)
296303
codes = self.codes
297304
if codes is not None:

lib/matplotlib/projections/polar.py

Lines changed: 10 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import math
2+
import warnings
23

34
import numpy as npy
45

@@ -32,15 +33,6 @@ class PolarTransform(Transform):
3233
output_dims = 2
3334
is_separable = False
3435

35-
def __init__(self, resolution):
36-
"""
37-
Create a new polar transform. Resolution is the number of steps
38-
to interpolate between each input line segment to approximate its
39-
path in curved polar space.
40-
"""
41-
Transform.__init__(self)
42-
self._resolution = resolution
43-
4436
def transform(self, tr):
4537
xy = npy.zeros(tr.shape, npy.float_)
4638
t = tr[:, 0:1]
@@ -59,15 +51,15 @@ def transform_path(self, path):
5951
vertices = path.vertices
6052
if len(vertices) == 2 and vertices[0, 0] == vertices[1, 0]:
6153
return Path(self.transform(vertices), path.codes)
62-
ipath = path.interpolated(self._resolution)
54+
ipath = path.interpolated(path._interpolation_steps)
6355
return Path(self.transform(ipath.vertices), ipath.codes)
6456
transform_path.__doc__ = Transform.transform_path.__doc__
6557

6658
transform_path_non_affine = transform_path
6759
transform_path_non_affine.__doc__ = Transform.transform_path_non_affine.__doc__
6860

6961
def inverted(self):
70-
return PolarAxes.InvertedPolarTransform(self._resolution)
62+
return PolarAxes.InvertedPolarTransform()
7163
inverted.__doc__ = Transform.inverted.__doc__
7264

7365
class PolarAffine(Affine2DBase):
@@ -109,10 +101,6 @@ class InvertedPolarTransform(Transform):
109101
output_dims = 2
110102
is_separable = False
111103

112-
def __init__(self, resolution):
113-
Transform.__init__(self)
114-
self._resolution = resolution
115-
116104
def transform(self, xy):
117105
x = xy[:, 0:1]
118106
y = xy[:, 1:]
@@ -123,7 +111,7 @@ def transform(self, xy):
123111
transform.__doc__ = Transform.transform.__doc__
124112

125113
def inverted(self):
126-
return PolarAxes.PolarTransform(self._resolution)
114+
return PolarAxes.PolarTransform()
127115
inverted.__doc__ = Transform.inverted.__doc__
128116

129117
class ThetaFormatter(Formatter):
@@ -177,8 +165,6 @@ def view_limits(self, vmin, vmax):
177165
return 0, vmax
178166

179167

180-
RESOLUTION = 1
181-
182168
def __init__(self, *args, **kwargs):
183169
"""
184170
Create a new Polar Axes for a polar plot.
@@ -192,8 +178,11 @@ def __init__(self, *args, **kwargs):
192178

193179
self._rpad = 0.05
194180
self.resolution = kwargs.pop('resolution', None)
195-
if self.resolution is None:
196-
self.resolution = self.RESOLUTION
181+
if self.resolution not in (None, 1):
182+
warnings.warn(
183+
"""The resolution kwarg to Polar plots is now ignored.
184+
If you need to interpolate data points, consider running
185+
cbook.simple_linear_interpolation on the data before passing to matplotlib.""")
197186
Axes.__init__(self, *args, **kwargs)
198187
self.set_aspect('equal', adjustable='box', anchor='C')
199188
self.cla()
@@ -221,7 +210,7 @@ def _set_lim_and_transforms(self):
221210
self.transScale = TransformWrapper(IdentityTransform())
222211

223212
# A (possibly non-linear) projection on the (already scaled) data
224-
self.transProjection = self.PolarTransform(self.resolution)
213+
self.transProjection = self.PolarTransform()
225214

226215
# An affine transformation on the data, generally to limit the
227216
# range of the axes

lib/matplotlib/transforms.py

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1119,7 +1119,8 @@ def transform_path(self, path):
11191119
In some cases, this transform may insert curves into the path
11201120
that began as line segments.
11211121
"""
1122-
return Path(self.transform(path.vertices), path.codes)
1122+
return Path(self.transform(path.vertices), path.codes,
1123+
path._interpolation_steps)
11231124

11241125
def transform_path_affine(self, path):
11251126
"""
@@ -1143,7 +1144,8 @@ def transform_path_non_affine(self, path):
11431144
``transform_path(path)`` is equivalent to
11441145
``transform_path_affine(transform_path_non_affine(values))``.
11451146
"""
1146-
return Path(self.transform_non_affine(path.vertices), path.codes)
1147+
return Path(self.transform_non_affine(path.vertices), path.codes,
1148+
self._interpolation_steps)
11471149

11481150
def transform_angles(self, angles, pts, radians=False, pushoff=1e-5):
11491151
"""
@@ -2181,7 +2183,8 @@ def _revalidate(self):
21812183
self._transformed_path = \
21822184
self._transform.transform_path_non_affine(self._path)
21832185
self._transformed_points = \
2184-
Path(self._transform.transform_non_affine(self._path.vertices))
2186+
Path(self._transform.transform_non_affine(self._path.vertices),
2187+
None, self._path._interpolation_steps)
21852188
self._invalid = 0
21862189

21872190
def get_transformed_points_and_affine(self):

0 commit comments

Comments
 (0)