Skip to content

Fix log transforms (fixes #3809) [back port to 1.4.x] #3863

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 7 commits into from
Dec 9, 2014
Merged
10 changes: 10 additions & 0 deletions lib/matplotlib/tests/test_transforms.py
Original file line number Diff line number Diff line change
Expand Up @@ -492,6 +492,16 @@ def test_transform_single_point():
r = t.transform_affine((1, 1))
assert r.shape == (2,)


@cleanup
def test_log_transform():
# Tests that the last line runs without exception (previously the
# transform would fail if one of the axes was logarithmic).
fig, ax = plt.subplots()
ax.set_yscale('log')
ax.transData.transform((1,1))


if __name__=='__main__':
import nose
nose.runmodule(argv=['-s','--with-doctest'], exit=False)
37 changes: 34 additions & 3 deletions lib/matplotlib/transforms.py
Original file line number Diff line number Diff line change
Expand Up @@ -1285,8 +1285,33 @@ def transform(self, values):

Accepts a numpy array of shape (N x :attr:`input_dims`) and
returns a numpy array of shape (N x :attr:`output_dims`).
"""
return self.transform_affine(self.transform_non_affine(values))

Alternatively, accepts a numpy array of length :attr:`input_dims`
and returns a numpy array of length :attr:`output_dims`.
"""
# Ensure that values is a 2d array (but remember whether
# we started with a 1d or 2d array).
values = np.asanyarray(values)
ndim = values.ndim
values = values.reshape((-1, self.input_dims))

# Transform the values
res = self.transform_affine(self.transform_non_affine(values))

# Convert the result back to the shape of the input values.
if ndim == 0:
assert not np.ma.is_masked(res) # just to be on the safe side
return res[0, 0]
if ndim == 1:
return res.reshape(-1)
elif ndim == 2:
return res
else:
raise ValueError(
"Input values must have shape (N x {dims}) "
"or ({dims}).".format(dims=self.input_dims))

return res

def transform_affine(self, values):
"""
Expand All @@ -1302,6 +1327,9 @@ def transform_affine(self, values):

Accepts a numpy array of shape (N x :attr:`input_dims`) and
returns a numpy array of shape (N x :attr:`output_dims`).

Alternatively, accepts a numpy array of length :attr:`input_dims`
and returns a numpy array of length :attr:`output_dims`.
"""
return self.get_affine().transform(values)

Expand All @@ -1318,6 +1346,9 @@ def transform_non_affine(self, values):

Accepts a numpy array of shape (N x :attr:`input_dims`) and
returns a numpy array of shape (N x :attr:`output_dims`).

Alternatively, accepts a numpy array of length :attr:`input_dims`
and returns a numpy array of length :attr:`output_dims`.
"""
return values

Expand Down Expand Up @@ -1944,7 +1975,7 @@ def get_matrix(self):
get_matrix.__doc__ = Affine2DBase.get_matrix.__doc__

def transform(self, points):
return points
return np.asanyarray(points)
transform.__doc__ = Affine2DBase.transform.__doc__

transform_affine = transform
Expand Down