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

Skip to content

Commit 2f2ff13

Browse files
Phil Elsonpelson
authored andcommitted
Several bugs fixed, particularly with Polar & Geo.
1 parent 8bbe2e5 commit 2f2ff13

5 files changed

Lines changed: 162 additions & 91 deletions

File tree

lib/matplotlib/projections/geo.py

Lines changed: 16 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -263,7 +263,7 @@ def __init__(self, resolution):
263263
Transform.__init__(self)
264264
self._resolution = resolution
265265

266-
def transform(self, ll):
266+
def transform_non_affine(self, ll):
267267
longitude = ll[:, 0:1]
268268
latitude = ll[:, 1:2]
269269

@@ -282,18 +282,12 @@ def transform(self, ll):
282282
x = (cos_latitude * ma.sin(half_long)) / sinc_alpha
283283
y = (ma.sin(latitude) / sinc_alpha)
284284
return np.concatenate((x.filled(0), y.filled(0)), 1)
285-
transform.__doc__ = Transform.transform.__doc__
286-
287-
transform_non_affine = transform
288285
transform_non_affine.__doc__ = Transform.transform_non_affine.__doc__
289286

290-
def transform_path(self, path):
287+
def transform_path_non_affine(self, path):
291288
vertices = path.vertices
292289
ipath = path.interpolated(self._resolution)
293290
return Path(self.transform(ipath.vertices), ipath.codes)
294-
transform_path.__doc__ = Transform.transform_path.__doc__
295-
296-
transform_path_non_affine = transform_path
297291
transform_path_non_affine.__doc__ = Transform.transform_path_non_affine.__doc__
298292

299293
def inverted(self):
@@ -309,10 +303,10 @@ def __init__(self, resolution):
309303
Transform.__init__(self)
310304
self._resolution = resolution
311305

312-
def transform(self, xy):
306+
def transform_non_affine(self, xy):
313307
# MGDTODO: Math is hard ;(
314308
return xy
315-
transform.__doc__ = Transform.transform.__doc__
309+
transform_non_affine.__doc__ = Transform.transform_non_affine.__doc__
316310

317311
def inverted(self):
318312
return AitoffAxes.AitoffTransform(self._resolution)
@@ -348,7 +342,7 @@ def __init__(self, resolution):
348342
Transform.__init__(self)
349343
self._resolution = resolution
350344

351-
def transform(self, ll):
345+
def transform_non_affine(self, ll):
352346
longitude = ll[:, 0:1]
353347
latitude = ll[:, 1:2]
354348

@@ -361,18 +355,12 @@ def transform(self, ll):
361355
x = (2.0 * sqrt2) * (cos_latitude * np.sin(half_long)) / alpha
362356
y = (sqrt2 * np.sin(latitude)) / alpha
363357
return np.concatenate((x, y), 1)
364-
transform.__doc__ = Transform.transform.__doc__
365-
366-
transform_non_affine = transform
367358
transform_non_affine.__doc__ = Transform.transform_non_affine.__doc__
368359

369-
def transform_path(self, path):
360+
def transform_path_non_affine(self, path):
370361
vertices = path.vertices
371362
ipath = path.interpolated(self._resolution)
372363
return Path(self.transform(ipath.vertices), ipath.codes)
373-
transform_path.__doc__ = Transform.transform_path.__doc__
374-
375-
transform_path_non_affine = transform_path
376364
transform_path_non_affine.__doc__ = Transform.transform_path_non_affine.__doc__
377365

378366
def inverted(self):
@@ -388,7 +376,7 @@ def __init__(self, resolution):
388376
Transform.__init__(self)
389377
self._resolution = resolution
390378

391-
def transform(self, xy):
379+
def transform_non_affine(self, xy):
392380
x = xy[:, 0:1]
393381
y = xy[:, 1:2]
394382

@@ -398,7 +386,7 @@ def transform(self, xy):
398386
longitude = 2 * np.arctan((z*x) / (2.0 * (2.0*z*z - 1.0)))
399387
latitude = np.arcsin(y*z)
400388
return np.concatenate((longitude, latitude), 1)
401-
transform.__doc__ = Transform.transform.__doc__
389+
transform_non_affine.__doc__ = Transform.transform_non_affine.__doc__
402390

403391
def inverted(self):
404392
return HammerAxes.HammerTransform(self._resolution)
@@ -434,7 +422,7 @@ def __init__(self, resolution):
434422
Transform.__init__(self)
435423
self._resolution = resolution
436424

437-
def transform(self, ll):
425+
def transform_non_affine(self, ll):
438426
def d(theta):
439427
delta = -(theta + np.sin(theta) - pi_sin_l) / (1 + np.cos(theta))
440428
return delta, np.abs(delta) > 0.001
@@ -466,18 +454,12 @@ def d(theta):
466454
xy[:,1] = np.sqrt(2.0) * np.sin(aux)
467455

468456
return xy
469-
transform.__doc__ = Transform.transform.__doc__
470-
471-
transform_non_affine = transform
472457
transform_non_affine.__doc__ = Transform.transform_non_affine.__doc__
473458

474-
def transform_path(self, path):
459+
def transform_path_non_affine(self, path):
475460
vertices = path.vertices
476461
ipath = path.interpolated(self._resolution)
477462
return Path(self.transform(ipath.vertices), ipath.codes)
478-
transform_path.__doc__ = Transform.transform_path.__doc__
479-
480-
transform_path_non_affine = transform_path
481463
transform_path_non_affine.__doc__ = Transform.transform_path_non_affine.__doc__
482464

483465
def inverted(self):
@@ -493,10 +475,10 @@ def __init__(self, resolution):
493475
Transform.__init__(self)
494476
self._resolution = resolution
495477

496-
def transform(self, xy):
478+
def transform_non_affine(self, xy):
497479
# MGDTODO: Math is hard ;(
498480
return xy
499-
transform.__doc__ = Transform.transform.__doc__
481+
transform_non_affine.__doc__ = Transform.transform_non_affine.__doc__
500482

501483
def inverted(self):
502484
return MollweideAxes.MollweideTransform(self._resolution)
@@ -534,7 +516,7 @@ def __init__(self, center_longitude, center_latitude, resolution):
534516
self._center_longitude = center_longitude
535517
self._center_latitude = center_latitude
536518

537-
def transform(self, ll):
519+
def transform_non_affine(self, ll):
538520
longitude = ll[:, 0:1]
539521
latitude = ll[:, 1:2]
540522
clong = self._center_longitude
@@ -555,18 +537,12 @@ def transform(self, ll):
555537
np.sin(clat)*cos_lat*cos_diff_long)
556538

557539
return np.concatenate((x, y), 1)
558-
transform.__doc__ = Transform.transform.__doc__
559-
560-
transform_non_affine = transform
561540
transform_non_affine.__doc__ = Transform.transform_non_affine.__doc__
562541

563-
def transform_path(self, path):
542+
def transform_path_non_affine(self, path):
564543
vertices = path.vertices
565544
ipath = path.interpolated(self._resolution)
566545
return Path(self.transform(ipath.vertices), ipath.codes)
567-
transform_path.__doc__ = Transform.transform_path.__doc__
568-
569-
transform_path_non_affine = transform_path
570546
transform_path_non_affine.__doc__ = Transform.transform_path_non_affine.__doc__
571547

572548
def inverted(self):
@@ -587,7 +563,7 @@ def __init__(self, center_longitude, center_latitude, resolution):
587563
self._center_longitude = center_longitude
588564
self._center_latitude = center_latitude
589565

590-
def transform(self, xy):
566+
def transform_non_affine(self, xy):
591567
x = xy[:, 0:1]
592568
y = xy[:, 1:2]
593569
clong = self._center_longitude
@@ -604,7 +580,7 @@ def transform(self, xy):
604580
(x*sin_c) / (p*np.cos(clat)*cos_c - y*np.sin(clat)*sin_c))
605581

606582
return np.concatenate((long, lat), 1)
607-
transform.__doc__ = Transform.transform.__doc__
583+
transform_non_affine.__doc__ = Transform.transform_non_affine.__doc__
608584

609585
def inverted(self):
610586
return LambertAxes.LambertTransform(

lib/matplotlib/projections/polar.py

Lines changed: 4 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ def __init__(self, axis=None, use_rmin=True):
4242
self._axis = axis
4343
self._use_rmin = use_rmin
4444

45-
def transform(self, tr):
45+
def transform_non_affine(self, tr):
4646
xy = np.empty(tr.shape, np.float_)
4747
if self._axis is not None:
4848
if self._use_rmin:
@@ -74,20 +74,14 @@ def transform(self, tr):
7474
y[:] = r * np.sin(t)
7575

7676
return xy
77-
transform.__doc__ = Transform.transform.__doc__
78-
79-
transform_non_affine = transform
8077
transform_non_affine.__doc__ = Transform.transform_non_affine.__doc__
8178

82-
def transform_path(self, path):
79+
def transform_path_non_affine(self, path):
8380
vertices = path.vertices
8481
if len(vertices) == 2 and vertices[0, 0] == vertices[1, 0]:
8582
return Path(self.transform(vertices), path.codes)
8683
ipath = path.interpolated(path._interpolation_steps)
8784
return Path(self.transform(ipath.vertices), ipath.codes)
88-
transform_path.__doc__ = Transform.transform_path.__doc__
89-
90-
transform_path_non_affine = transform_path
9185
transform_path_non_affine.__doc__ = Transform.transform_path_non_affine.__doc__
9286

9387
def inverted(self):
@@ -138,7 +132,7 @@ def __init__(self, axis=None, use_rmin=True):
138132
self._axis = axis
139133
self._use_rmin = use_rmin
140134

141-
def transform(self, xy):
135+
def transform_non_affine(self, xy):
142136
if self._axis is not None:
143137
if self._use_rmin:
144138
rmin = self._axis.viewLim.ymin
@@ -163,7 +157,7 @@ def transform(self, xy):
163157
r += rmin
164158

165159
return np.concatenate((theta, r), 1)
166-
transform.__doc__ = Transform.transform.__doc__
160+
transform_non_affine.__doc__ = Transform.transform_non_affine.__doc__
167161

168162
def inverted(self):
169163
return PolarAxes.PolarTransform(self._axis, self._use_rmin)

lib/matplotlib/tests/test_axes.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import matplotlib
44
from matplotlib.testing.decorators import image_comparison, knownfailureif
55
import matplotlib.pyplot as plt
6+
import matplotlib.transforms as mtrans
67

78

89
@image_comparison(baseline_images=['formatter_ticker_001',

lib/matplotlib/tests/test_transforms.py

Lines changed: 66 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -167,22 +167,30 @@ def test_clipping_of_log():
167167
assert np.allclose(tpoints[-1], tpoints[0])
168168

169169

170-
class BasicTransformTests(unittest.TestCase):
171-
def setUp(self):
172-
class NonAffineForTest(mtrans.Transform):
173-
is_affine = False
174-
output_dims = 2
175-
input_dims = 2
170+
class NonAffineForTest(mtrans.Transform):
171+
"""
172+
A class which looks like a non affine transform, but does whatever
173+
the given transform does (even if it is affine). This is very useful
174+
for testing NonAffine behaviour with a simple Affine transform.
175+
176+
"""
177+
is_affine = False
178+
output_dims = 2
179+
input_dims = 2
176180

177-
def __init__(self, real_trans, *args, **kwargs):
178-
self.real_trans = real_trans
179-
r = mtrans.Transform.__init__(self, *args, **kwargs)
181+
def __init__(self, real_trans, *args, **kwargs):
182+
self.real_trans = real_trans
183+
r = mtrans.Transform.__init__(self, *args, **kwargs)
180184

181-
def transform_non_affine(self, values):
182-
return self.real_trans.transform(values)
185+
def transform_non_affine(self, values):
186+
return self.real_trans.transform(values)
183187

184-
def transform_path_non_affine(self, path):
185-
return self.real_trans.transform_path(path)
188+
def transform_path_non_affine(self, path):
189+
return self.real_trans.transform_path(path)
190+
191+
192+
class BasicTransformTests(unittest.TestCase):
193+
def setUp(self):
186194

187195
self.ta1 = mtrans.Affine2D(shorthand_name='ta1').rotate(np.pi / 2)
188196
self.ta2 = mtrans.Affine2D(shorthand_name='ta2').translate(10, 0)
@@ -214,12 +222,30 @@ def test_left_to_right_iteration(self):
214222
self.tn2 + self.ta3,
215223
self.ta3,
216224
]
217-
r = list(self.stack3._iter_break_from_left_to_right())
225+
r = [rh for lh, rh in stack3._iter_break_from_left_to_right()]
218226
self.assertEqual(len(r), len(target_transforms))
219227

220228
for target_stack, stack in itertools.izip(target_transforms, r):
221229
self.assertEqual(target_stack, stack)
222230

231+
def test_transform_shortcuts(self):
232+
self.assertEqual(self.stack1 - self.stack2_subset, self.ta1)
233+
self.assertEqual(self.stack2 - self.stack2_subset, self.ta1)
234+
235+
# check that we cannot find a chain from the subset back to the superset
236+
# (since the inverse of the Transform is not defined.)
237+
self.assertRaises(ValueError, self.stack2_subset.__sub__, self.stack2)
238+
self.assertRaises(ValueError, self.stack1.__sub__, self.stack2)
239+
240+
aff1 = self.ta1 + (self.ta2 + self.ta3)
241+
aff2 = self.ta2 + self.ta3
242+
243+
self.assertEqual(aff1 - aff2, self.ta1)
244+
self.assertEqual(aff1 - self.ta2, aff1 + self.ta2.inverted())
245+
246+
self.assertEqual(self.stack1 - self.ta3, self.ta1 + (self.tn1 + self.ta2))
247+
self.assertEqual(self.stack2 - self.ta3, self.ta1 + self.tn1 + self.ta2)
248+
223249
def test_contains_branch(self):
224250
r1 = (self.ta2 + self.ta1)
225251
r2 = (self.ta2 + self.ta1)
@@ -247,6 +273,9 @@ def test_contains_branch(self):
247273
self.assertFalse(self.stack1.contains_branch((self.tn1 + self.ta2)))
248274

249275
def test_affine_simplification(self):
276+
# tests that a transform stack only calls as much is absolutely necessary
277+
# "non-affine" allowing the best possible optimization with complex
278+
# transformation stacks.
250279
points = np.array([[0, 0], [10, 20], [np.nan, 1], [-1, 0]], dtype=np.float64)
251280
na_pts = self.stack1.transform_non_affine(points)
252281
all_pts = self.stack1.transform(points)
@@ -276,6 +305,28 @@ def test_affine_simplification(self):
276305
np_test.assert_array_equal(expected_result, result)
277306

278307

308+
class TestTransformPlotInterface(unittest.TestCase):
309+
def tearDown(self):
310+
plt.close()
311+
312+
def test_line_extents_affine(self):
313+
ax = plt.axes()
314+
offset = mtrans.Affine2D().translate(10, 10)
315+
plt.plot(range(10), transform=offset + ax.transData)
316+
expeted_data_lim = np.array([[0., 0.], [9., 9.]]) + 10
317+
np.testing.assert_array_almost_equal(ax.dataLim.get_points(),
318+
expeted_data_lim)
319+
320+
def test_line_extents_non_affine(self):
321+
ax = plt.axes()
322+
offset = mtrans.Affine2D().translate(10, 10)
323+
na_offset = NonAffineForTest(mtrans.Affine2D().translate(10, 10))
324+
plt.plot(range(10), transform=offset + na_offset + ax.transData)
325+
expeted_data_lim = np.array([[0., 0.], [9., 9.]]) + 20
326+
np.testing.assert_array_almost_equal(ax.dataLim.get_points(),
327+
expeted_data_lim)
328+
329+
279330
if __name__=='__main__':
280331
import nose
281-
nose.runmodule(argv=['-s','--with-doctest'], exit=False)
332+
nose.runmodule(argv=['-s','--with-doctest'], exit=False)

0 commit comments

Comments
 (0)