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

Skip to content
Merged
Prev Previous commit
Next Next commit
Several bugs fixed, particularly with Polar & Geo.
  • Loading branch information
Phil Elson authored and pelson committed Aug 20, 2012
commit 2f2ff13ad6331257f30fc4f9649c43a0b883ad68
56 changes: 16 additions & 40 deletions lib/matplotlib/projections/geo.py
Original file line number Diff line number Diff line change
Expand Up @@ -263,7 +263,7 @@ def __init__(self, resolution):
Transform.__init__(self)
self._resolution = resolution

def transform(self, ll):
def transform_non_affine(self, ll):
longitude = ll[:, 0:1]
latitude = ll[:, 1:2]

Expand All @@ -282,18 +282,12 @@ def transform(self, ll):
x = (cos_latitude * ma.sin(half_long)) / sinc_alpha
y = (ma.sin(latitude) / sinc_alpha)
return np.concatenate((x.filled(0), y.filled(0)), 1)
transform.__doc__ = Transform.transform.__doc__

transform_non_affine = transform
transform_non_affine.__doc__ = Transform.transform_non_affine.__doc__

def transform_path(self, path):
def transform_path_non_affine(self, path):
vertices = path.vertices
ipath = path.interpolated(self._resolution)
return Path(self.transform(ipath.vertices), ipath.codes)
transform_path.__doc__ = Transform.transform_path.__doc__

transform_path_non_affine = transform_path
transform_path_non_affine.__doc__ = Transform.transform_path_non_affine.__doc__

def inverted(self):
Expand All @@ -309,10 +303,10 @@ def __init__(self, resolution):
Transform.__init__(self)
self._resolution = resolution

def transform(self, xy):
def transform_non_affine(self, xy):
# MGDTODO: Math is hard ;(
return xy
transform.__doc__ = Transform.transform.__doc__
transform_non_affine.__doc__ = Transform.transform_non_affine.__doc__

def inverted(self):
return AitoffAxes.AitoffTransform(self._resolution)
Expand Down Expand Up @@ -348,7 +342,7 @@ def __init__(self, resolution):
Transform.__init__(self)
self._resolution = resolution

def transform(self, ll):
def transform_non_affine(self, ll):
longitude = ll[:, 0:1]
latitude = ll[:, 1:2]

Expand All @@ -361,18 +355,12 @@ def transform(self, ll):
x = (2.0 * sqrt2) * (cos_latitude * np.sin(half_long)) / alpha
y = (sqrt2 * np.sin(latitude)) / alpha
return np.concatenate((x, y), 1)
transform.__doc__ = Transform.transform.__doc__

transform_non_affine = transform
transform_non_affine.__doc__ = Transform.transform_non_affine.__doc__

def transform_path(self, path):
def transform_path_non_affine(self, path):
vertices = path.vertices
ipath = path.interpolated(self._resolution)
return Path(self.transform(ipath.vertices), ipath.codes)
transform_path.__doc__ = Transform.transform_path.__doc__

transform_path_non_affine = transform_path
transform_path_non_affine.__doc__ = Transform.transform_path_non_affine.__doc__

def inverted(self):
Expand All @@ -388,7 +376,7 @@ def __init__(self, resolution):
Transform.__init__(self)
self._resolution = resolution

def transform(self, xy):
def transform_non_affine(self, xy):
x = xy[:, 0:1]
y = xy[:, 1:2]

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

def inverted(self):
return HammerAxes.HammerTransform(self._resolution)
Expand Down Expand Up @@ -434,7 +422,7 @@ def __init__(self, resolution):
Transform.__init__(self)
self._resolution = resolution

def transform(self, ll):
def transform_non_affine(self, ll):
def d(theta):
delta = -(theta + np.sin(theta) - pi_sin_l) / (1 + np.cos(theta))
return delta, np.abs(delta) > 0.001
Expand Down Expand Up @@ -466,18 +454,12 @@ def d(theta):
xy[:,1] = np.sqrt(2.0) * np.sin(aux)

return xy
transform.__doc__ = Transform.transform.__doc__

transform_non_affine = transform
transform_non_affine.__doc__ = Transform.transform_non_affine.__doc__

def transform_path(self, path):
def transform_path_non_affine(self, path):
vertices = path.vertices
ipath = path.interpolated(self._resolution)
return Path(self.transform(ipath.vertices), ipath.codes)
transform_path.__doc__ = Transform.transform_path.__doc__

transform_path_non_affine = transform_path
transform_path_non_affine.__doc__ = Transform.transform_path_non_affine.__doc__

def inverted(self):
Expand All @@ -493,10 +475,10 @@ def __init__(self, resolution):
Transform.__init__(self)
self._resolution = resolution

def transform(self, xy):
def transform_non_affine(self, xy):
# MGDTODO: Math is hard ;(
return xy
transform.__doc__ = Transform.transform.__doc__
transform_non_affine.__doc__ = Transform.transform_non_affine.__doc__

def inverted(self):
return MollweideAxes.MollweideTransform(self._resolution)
Expand Down Expand Up @@ -534,7 +516,7 @@ def __init__(self, center_longitude, center_latitude, resolution):
self._center_longitude = center_longitude
self._center_latitude = center_latitude

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

return np.concatenate((x, y), 1)
transform.__doc__ = Transform.transform.__doc__

transform_non_affine = transform
transform_non_affine.__doc__ = Transform.transform_non_affine.__doc__

def transform_path(self, path):
def transform_path_non_affine(self, path):
vertices = path.vertices
ipath = path.interpolated(self._resolution)
return Path(self.transform(ipath.vertices), ipath.codes)
transform_path.__doc__ = Transform.transform_path.__doc__

transform_path_non_affine = transform_path
transform_path_non_affine.__doc__ = Transform.transform_path_non_affine.__doc__

def inverted(self):
Expand All @@ -587,7 +563,7 @@ def __init__(self, center_longitude, center_latitude, resolution):
self._center_longitude = center_longitude
self._center_latitude = center_latitude

def transform(self, xy):
def transform_non_affine(self, xy):
x = xy[:, 0:1]
y = xy[:, 1:2]
clong = self._center_longitude
Expand All @@ -604,7 +580,7 @@ def transform(self, xy):
(x*sin_c) / (p*np.cos(clat)*cos_c - y*np.sin(clat)*sin_c))

return np.concatenate((long, lat), 1)
transform.__doc__ = Transform.transform.__doc__
transform_non_affine.__doc__ = Transform.transform_non_affine.__doc__

def inverted(self):
return LambertAxes.LambertTransform(
Expand Down
14 changes: 4 additions & 10 deletions lib/matplotlib/projections/polar.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ def __init__(self, axis=None, use_rmin=True):
self._axis = axis
self._use_rmin = use_rmin

def transform(self, tr):
def transform_non_affine(self, tr):
xy = np.empty(tr.shape, np.float_)
if self._axis is not None:
if self._use_rmin:
Expand Down Expand Up @@ -74,20 +74,14 @@ def transform(self, tr):
y[:] = r * np.sin(t)

return xy
transform.__doc__ = Transform.transform.__doc__

transform_non_affine = transform
transform_non_affine.__doc__ = Transform.transform_non_affine.__doc__

def transform_path(self, path):
def transform_path_non_affine(self, path):
vertices = path.vertices
if len(vertices) == 2 and vertices[0, 0] == vertices[1, 0]:
return Path(self.transform(vertices), path.codes)
ipath = path.interpolated(path._interpolation_steps)
return Path(self.transform(ipath.vertices), ipath.codes)
transform_path.__doc__ = Transform.transform_path.__doc__

transform_path_non_affine = transform_path
transform_path_non_affine.__doc__ = Transform.transform_path_non_affine.__doc__

def inverted(self):
Expand Down Expand Up @@ -138,7 +132,7 @@ def __init__(self, axis=None, use_rmin=True):
self._axis = axis
self._use_rmin = use_rmin

def transform(self, xy):
def transform_non_affine(self, xy):
if self._axis is not None:
if self._use_rmin:
rmin = self._axis.viewLim.ymin
Expand All @@ -163,7 +157,7 @@ def transform(self, xy):
r += rmin

return np.concatenate((theta, r), 1)
transform.__doc__ = Transform.transform.__doc__
transform_non_affine.__doc__ = Transform.transform_non_affine.__doc__

def inverted(self):
return PolarAxes.PolarTransform(self._axis, self._use_rmin)
Expand Down
1 change: 1 addition & 0 deletions lib/matplotlib/tests/test_axes.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import matplotlib
from matplotlib.testing.decorators import image_comparison, knownfailureif
import matplotlib.pyplot as plt
import matplotlib.transforms as mtrans


@image_comparison(baseline_images=['formatter_ticker_001',
Expand Down
81 changes: 66 additions & 15 deletions lib/matplotlib/tests/test_transforms.py
Original file line number Diff line number Diff line change
Expand Up @@ -167,22 +167,30 @@ def test_clipping_of_log():
assert np.allclose(tpoints[-1], tpoints[0])


class BasicTransformTests(unittest.TestCase):
def setUp(self):
class NonAffineForTest(mtrans.Transform):
is_affine = False
output_dims = 2
input_dims = 2
class NonAffineForTest(mtrans.Transform):
"""
A class which looks like a non affine transform, but does whatever
the given transform does (even if it is affine). This is very useful
for testing NonAffine behaviour with a simple Affine transform.

"""
is_affine = False
output_dims = 2
input_dims = 2

def __init__(self, real_trans, *args, **kwargs):
self.real_trans = real_trans
r = mtrans.Transform.__init__(self, *args, **kwargs)
def __init__(self, real_trans, *args, **kwargs):
self.real_trans = real_trans
r = mtrans.Transform.__init__(self, *args, **kwargs)

def transform_non_affine(self, values):
return self.real_trans.transform(values)
def transform_non_affine(self, values):
return self.real_trans.transform(values)

def transform_path_non_affine(self, path):
return self.real_trans.transform_path(path)
def transform_path_non_affine(self, path):
return self.real_trans.transform_path(path)


class BasicTransformTests(unittest.TestCase):
def setUp(self):

self.ta1 = mtrans.Affine2D(shorthand_name='ta1').rotate(np.pi / 2)
self.ta2 = mtrans.Affine2D(shorthand_name='ta2').translate(10, 0)
Expand Down Expand Up @@ -214,12 +222,30 @@ def test_left_to_right_iteration(self):
self.tn2 + self.ta3,
self.ta3,
]
r = list(self.stack3._iter_break_from_left_to_right())
r = [rh for lh, rh in stack3._iter_break_from_left_to_right()]
self.assertEqual(len(r), len(target_transforms))

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

def test_transform_shortcuts(self):
self.assertEqual(self.stack1 - self.stack2_subset, self.ta1)
self.assertEqual(self.stack2 - self.stack2_subset, self.ta1)

# check that we cannot find a chain from the subset back to the superset
# (since the inverse of the Transform is not defined.)
self.assertRaises(ValueError, self.stack2_subset.__sub__, self.stack2)
self.assertRaises(ValueError, self.stack1.__sub__, self.stack2)

aff1 = self.ta1 + (self.ta2 + self.ta3)
aff2 = self.ta2 + self.ta3

self.assertEqual(aff1 - aff2, self.ta1)
self.assertEqual(aff1 - self.ta2, aff1 + self.ta2.inverted())

self.assertEqual(self.stack1 - self.ta3, self.ta1 + (self.tn1 + self.ta2))
self.assertEqual(self.stack2 - self.ta3, self.ta1 + self.tn1 + self.ta2)

def test_contains_branch(self):
r1 = (self.ta2 + self.ta1)
r2 = (self.ta2 + self.ta1)
Expand Down Expand Up @@ -247,6 +273,9 @@ def test_contains_branch(self):
self.assertFalse(self.stack1.contains_branch((self.tn1 + self.ta2)))

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


class TestTransformPlotInterface(unittest.TestCase):
def tearDown(self):
plt.close()

def test_line_extents_affine(self):
ax = plt.axes()
offset = mtrans.Affine2D().translate(10, 10)
plt.plot(range(10), transform=offset + ax.transData)
expeted_data_lim = np.array([[0., 0.], [9., 9.]]) + 10
np.testing.assert_array_almost_equal(ax.dataLim.get_points(),
expeted_data_lim)

def test_line_extents_non_affine(self):
ax = plt.axes()
offset = mtrans.Affine2D().translate(10, 10)
na_offset = NonAffineForTest(mtrans.Affine2D().translate(10, 10))
plt.plot(range(10), transform=offset + na_offset + ax.transData)
expeted_data_lim = np.array([[0., 0.], [9., 9.]]) + 20
np.testing.assert_array_almost_equal(ax.dataLim.get_points(),
expeted_data_lim)


if __name__=='__main__':
import nose
nose.runmodule(argv=['-s','--with-doctest'], exit=False)
nose.runmodule(argv=['-s','--with-doctest'], exit=False)
Loading