diff --git a/lib/matplotlib/tests/test_transforms.py b/lib/matplotlib/tests/test_transforms.py index af9cea700a38..c138b5937db9 100644 --- a/lib/matplotlib/tests/test_transforms.py +++ b/lib/matplotlib/tests/test_transforms.py @@ -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) diff --git a/lib/matplotlib/transforms.py b/lib/matplotlib/transforms.py index c8848eca900f..0c7a48cbf7c7 100644 --- a/lib/matplotlib/transforms.py +++ b/lib/matplotlib/transforms.py @@ -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): """ @@ -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) @@ -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 @@ -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