Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 095830e

Browse filesBrowse files
authored
Merge pull request #14292 from meeseeksmachine/auto-backport-of-pr-14289-on-v3.1.x
Backport PR #14289 on branch v3.1.x (BUG: Fix performance regression when plotting values from Numpy array sub-classes)
2 parents c80bc34 + c1b5322 commit 095830e
Copy full SHA for 095830e

File tree

Expand file treeCollapse file tree

2 files changed

+38
-1
lines changed
Filter options
Expand file treeCollapse file tree

2 files changed

+38
-1
lines changed

‎lib/matplotlib/cbook/__init__.py

Copy file name to clipboardExpand all lines: lib/matplotlib/cbook/__init__.py
+1-1Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1420,7 +1420,7 @@ def _reshape_2D(X, name):
14201420
X = np.atleast_1d(X.T if isinstance(X, np.ndarray) else np.asarray(X))
14211421
if len(X) == 0:
14221422
return [[]]
1423-
if X.ndim == 1 and not isinstance(X[0], collections.abc.Iterable):
1423+
elif X.ndim == 1 and np.ndim(X[0]) == 0:
14241424
# 1D array of scalars: directly return it.
14251425
return [X]
14261426
elif X.ndim in [1, 2]:

‎lib/matplotlib/tests/test_cbook.py

Copy file name to clipboardExpand all lines: lib/matplotlib/tests/test_cbook.py
+37Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -494,8 +494,10 @@ def test_flatiter():
494494

495495

496496
def test_reshape2d():
497+
497498
class dummy():
498499
pass
500+
499501
xnew = cbook._reshape_2D([], 'x')
500502
assert np.shape(xnew) == (1, 0)
501503

@@ -517,6 +519,41 @@ class dummy():
517519
xnew = cbook._reshape_2D(x, 'x')
518520
assert np.shape(xnew) == (5, 3)
519521

522+
# Now test with a list of lists with different lengths, which means the
523+
# array will internally be converted to a 1D object array of lists
524+
x = [[1, 2, 3], [3, 4], [2]]
525+
xnew = cbook._reshape_2D(x, 'x')
526+
assert isinstance(xnew, list)
527+
assert isinstance(xnew[0], np.ndarray) and xnew[0].shape == (3,)
528+
assert isinstance(xnew[1], np.ndarray) and xnew[1].shape == (2,)
529+
assert isinstance(xnew[2], np.ndarray) and xnew[2].shape == (1,)
530+
531+
# We now need to make sure that this works correctly for Numpy subclasses
532+
# where iterating over items can return subclasses too, which may be
533+
# iterable even if they are scalars. To emulate this, we make a Numpy
534+
# array subclass that returns Numpy 'scalars' when iterating or accessing
535+
# values, and these are technically iterable if checking for example
536+
# isinstance(x, collections.abc.Iterable).
537+
538+
class ArraySubclass(np.ndarray):
539+
540+
def __iter__(self):
541+
for value in super().__iter__():
542+
yield np.array(value)
543+
544+
def __getitem__(self, item):
545+
return np.array(super().__getitem__(item))
546+
547+
v = np.arange(10, dtype=float)
548+
x = ArraySubclass((10,), dtype=float, buffer=v.data)
549+
550+
xnew = cbook._reshape_2D(x, 'x')
551+
552+
# We check here that the array wasn't split up into many individual
553+
# ArraySubclass, which is what used to happen due to a bug in _reshape_2D
554+
assert len(xnew) == 1
555+
assert isinstance(xnew[0], ArraySubclass)
556+
520557

521558
def test_contiguous_regions():
522559
a, b, c = 3, 4, 5

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.