Skip to content

Commit

Permalink
Merge pull request #5106 from jkseppan/0d-views
Browse files Browse the repository at this point in the history
FIX: array_view construction for empty arrays
  • Loading branch information
tacaswell committed Oct 2, 2015
2 parents e5b7e45 + 123deb5 commit 15b8629
Show file tree
Hide file tree
Showing 6 changed files with 49 additions and 18 deletions.
12 changes: 8 additions & 4 deletions lib/matplotlib/collections.py
Expand Up @@ -80,9 +80,13 @@ class Collection(artist.Artist, cm.ScalarMappable):
# _offsets must be a Nx2 array!
_offsets.shape = (0, 2)
_transOffset = transforms.IdentityTransform()
_transforms = []


#: Either a list of 3x3 arrays or an Nx3x3 array of transforms, suitable
#: for the `all_transforms` argument to
#: :meth:`~matplotlib.backend_bases.RendererBase.draw_path_collection`;
#: each 3x3 array is used to initialize an
#: :class:`~matplotlib.transforms.Affine2D` object.
#: Each kind of collection defines this based on its arguments.
_transforms = np.empty((0, 3, 3))

def __init__(self,
edgecolors=None,
Expand Down Expand Up @@ -1515,7 +1519,7 @@ def __init__(self, widths, heights, angles, units='points', **kwargs):
self._angles = np.asarray(angles).ravel() * (np.pi / 180.0)
self._units = units
self.set_transform(transforms.IdentityTransform())
self._transforms = []
self._transforms = np.empty((0, 3, 3))
self._paths = [mpath.Path.unit_circle()]

def _set_transforms(self):
Expand Down
3 changes: 2 additions & 1 deletion lib/matplotlib/path.py
Expand Up @@ -988,7 +988,8 @@ def get_path_collection_extents(
if len(paths) == 0:
raise ValueError("No paths provided")
return Bbox.from_extents(*_path.get_path_collection_extents(
master_transform, paths, transforms, offsets, offset_transform))
master_transform, paths, np.atleast_3d(transforms),
offsets, offset_transform))


def get_paths_extents(paths, transforms=[]):
Expand Down
15 changes: 15 additions & 0 deletions lib/matplotlib/tests/test_transforms.py
Expand Up @@ -561,6 +561,21 @@ def test_nonsingular():
assert_array_equal(out, zero_expansion)


def test_invalid_arguments():
t = mtrans.Affine2D()
# There are two different exceptions, since the wrong number of
# dimensions is caught when constructing an array_view, and that
# raises a ValueError, and a wrong shape with a possible number
# of dimensions is caught by our CALL_CPP macro, which always
# raises the less precise RuntimeError.
assert_raises(ValueError, t.transform, 1)
assert_raises(ValueError, t.transform, [[[1]]])
assert_raises(RuntimeError, t.transform, [])
assert_raises(RuntimeError, t.transform, [1])
assert_raises(RuntimeError, t.transform, [[1]])
assert_raises(RuntimeError, t.transform, [[1, 2, 3]])


if __name__ == '__main__':
import nose
nose.runmodule(argv=['-s', '--with-doctest'], exit=False)
3 changes: 2 additions & 1 deletion lib/matplotlib/transforms.py
Expand Up @@ -666,7 +666,8 @@ def count_overlaps(self, bboxes):
bboxes is a sequence of :class:`BboxBase` objects
"""
return count_bboxes_overlapping_bbox(self, [np.array(x) for x in bboxes])
return count_bboxes_overlapping_bbox(
self, np.atleast_3d([np.array(x) for x in bboxes]))

def expanded(self, sw, sh):
"""
Expand Down
15 changes: 10 additions & 5 deletions src/_path_wrapper.cpp
Expand Up @@ -439,11 +439,16 @@ static PyObject *Py_affine_transform(PyObject *self, PyObject *args, PyObject *k
CALL_CPP("affine_transform", (affine_transform_2d(vertices, trans, result)));
return result.pyobj();
} catch (py::exception) {
numpy::array_view<double, 1> vertices(vertices_obj);
npy_intp dims[] = { vertices.dim(0) };
numpy::array_view<double, 1> result(dims);
CALL_CPP("affine_transform", (affine_transform_1d(vertices, trans, result)));
return result.pyobj();
PyErr_Clear();
try {
numpy::array_view<double, 1> vertices(vertices_obj);
npy_intp dims[] = { vertices.dim(0) };
numpy::array_view<double, 1> result(dims);
CALL_CPP("affine_transform", (affine_transform_1d(vertices, trans, result)));
return result.pyobj();
} catch (py::exception) {
return NULL;
}
}
}

Expand Down
19 changes: 12 additions & 7 deletions src/numpy_cpp.h
Expand Up @@ -443,13 +443,18 @@ class array_view : public detail::array_view_accessors<array_view, T, ND>
m_data = NULL;
m_shape = zeros;
m_strides = zeros;
} else if (PyArray_NDIM(tmp) != ND) {
PyErr_Format(PyExc_ValueError,
"Expected %d-dimensional array, got %d",
ND,
PyArray_NDIM(tmp));
Py_DECREF(tmp);
return 0;
if (PyArray_NDIM(tmp) == 0 && ND == 0) {
m_arr = tmp;
return 1;
}
}
if (PyArray_NDIM(tmp) != ND) {
PyErr_Format(PyExc_ValueError,
"Expected %d-dimensional array, got %d",
ND,
PyArray_NDIM(tmp));
Py_DECREF(tmp);
return 0;
}

/* Copy some of the data to the view object for faster access */
Expand Down

0 comments on commit 15b8629

Please sign in to comment.