8000 Merge pull request #5106 from jkseppan/0d-views · matplotlib/matplotlib@15b8629 · GitHub
[go: up one dir, main page]

Skip to content

Commit 15b8629

Browse files
committed
Merge pull request #5106 from jkseppan/0d-views
FIX: array_view construction for empty arrays
2 parents e5b7e45 + 123deb5 commit 15b8629

File tree

6 files changed

+49
-18
lines changed

6 files changed

+49
-18
lines changed

lib/matplotlib/collections.py

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -80,9 +80,13 @@ class Collection(artist.Artist, cm.ScalarMappable):
8080
# _offsets must be a Nx2 array!
8181
_offsets.shape = (0, 2)
8282
_transOffset = transforms.IdentityTransform()
83-
_transforms = []
84-
85-
83+
#: Either a list of 3x3 arrays or an Nx3x3 array of transforms, suitable
84+
#: for the `all_transforms` argument to
85+
#: :meth:`~matplotlib.backend_bases.RendererBase.draw_path_collection`;
86+
#: each 3x3 array is used to initialize an
87+
#: :class:`~matplotlib.transforms.Affine2D` object.
88+
#: Each kind of collection defines this based on its arguments.
89+
_transforms = np.empty((0, 3, 3))
8690

8791
def __init__(self,
8892
edgecolors=None,
@@ -1515,7 +1519,7 @@ def __init__(self, widths, heights, angles, units='points', **kwargs):
15151519
self._angles = np.asarray(angles).ravel() * (np.pi / 180.0)
15161520
self._units = units
15171521
self.set_transform(transforms.IdentityTransform())
1518-
self._transforms = []
1522+
self._transforms = np.empty((0, 3, 3))
15191523
self._paths = [mpath.Path.unit_circle()]
15201524

15211525
def _set_transforms(self):

lib/matplotlib/path.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -988,7 +988,8 @@ def get_path_collection_extents(
988988
if len(paths) == 0:
989989
raise ValueError("No paths provided")
990990
return Bbox.from_extents(*_path.get_path_collection_extents(
991-
master_transform, paths, transforms, offsets, offset_transform))
991+
master_transform, paths, np.atleast_3d(transforms),
992+
offsets, offset_transform))
992993

993994

994995
def get_paths_extents(paths, transforms=[]):

lib/matplotlib/tests/test_transforms.py

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -561,6 +561,21 @@ def test_nonsingular():
561561
assert_array_equal(out, zero_expansion)
562562

563563

564+
def test_invalid_arguments():
565+
t = mtrans.Affine2D()
566+
# There are two different exceptions, since the wrong number of
567+
# dimensions is caught when constructing an array_view, and that
568+
# raises a ValueError, and a wrong shape with a possible number
569+
# of dimensions is caught by our CALL_CPP macro, which always
570+
# raises the less precise RuntimeError.
571+
assert_raises(ValueError, t.transform, 1)
572+
assert_raises(ValueError, t.transform, [[[1]]])
573+
assert_raises(RuntimeError, t.transform, [])
574+
assert_raises(RuntimeError, t.transform, [1])
575+
assert_raises(RuntimeError, t.transform, [[1]])
576+
assert_raises(RuntimeError, t.transform, [[1, 2, 3]])
577+
578+
564579
if __name__ == '__main__':
565580
import nose
566581
nose.runmodule(argv=['-s', '--with-doctest'], exit=False)

lib/matplotlib/transforms.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -666,7 +666,8 @@ def count_overlaps(self, bboxes):
666666
667667
bboxes is a sequence of :class:`BboxBase` objects
668668
"""
669-
return count_bboxes_overlapping_bbox(self, [np.array(x) for x in bboxes])
669+
return count_bboxes_overlapping_bbox(
670+
self, np.atleast_3d([np.array(x) for x in bboxes]))
670671

671672
def expanded(self, sw, sh):
672673
"""

src/_path_wrapper.cpp

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -439,11 +439,16 @@ static PyObject *Py_affine_transform(PyObject *self, PyObject *args, PyObject *k
439439
CALL_CPP("affine_transform", (affine_transform_2d(vertices, trans, result)));
440440
return result.pyobj();
441441
} catch (py::exception) {
442-
numpy::array_view<double, 1> vertices(vertices_obj);
443-
npy_intp dims[] = { vertices.dim(0) };
444-
numpy::array_view<double, 1> result(dims);
445-
CALL_CPP("affine_transform", (affine_transform_1d(vertices, trans, result)));
446-
return result.pyobj();
442+
PyErr_Clear();
443+
try {
444+
numpy::array_view<double, 1> vertices(vertices_obj);
445+
npy_intp dims[] = { vertices.dim(0) };
446+
numpy::array_view<double, 1> result(dims);
447+
CALL_CPP("affine_transform", (affine_transform_1d(vertices, trans, result)));
448+
return result.pyobj();
449+
} catch (py::exception) {
450+
return NULL;
451+
}
447452
}
448453
}
449454

src/numpy_cpp.h

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -443,13 +443,18 @@ class array_view : public detail::array_view_accessors<array_view, T, ND>
443443
m_data = NULL;
444444
m_shape = zeros;
445445
m_strides = zeros;
446-
} else if (PyArray_NDIM(tmp) != ND) {
447-
PyErr_Format(PyExc_ValueError,
448-
"Expected %d-dimensional array, got %d",
449-
ND,
450-
PyArray_NDIM(tmp));
451-
Py_DECREF(tmp);
452-
return 0;
446+
if (PyArray_NDIM(tmp) == 0 && ND == 0) {
447+
m_arr = tmp;
448+
return 1;
449+
}
450+
}
451+
if (PyArray_NDIM(tmp) != ND) {
452+
PyErr_Format(PyExc_ValueError,
453+
"Expected %d-dimensional array, got %d",
454+
ND,
455+
PyArray_NDIM(tmp));
456+
Py_DECREF(tmp);
457+
return 0;
453458
}
454459

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

0 commit comments

Comments
 (0)
0