Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Prepare for ragged array warnings in NumPy 1.19 #17289

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
May 22, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 6 additions & 4 deletions lib/matplotlib/axes/_axes.py
Original file line number Diff line number Diff line change
Expand Up @@ -3778,7 +3778,7 @@ def boxplot(self, x, notch=None, sym=None, vert=None, whis=None,
stats['med'] = med

if conf_intervals is not None:
if np.shape(conf_intervals)[0] != len(bxpstats):
if len(conf_intervals) != len(bxpstats):
raise ValueError(
"'conf_intervals' and 'x' have different lengths")
else:
Expand Down Expand Up @@ -6555,8 +6555,6 @@ def hist(self, x, bins=None, range=None, density=False, weights=None,
if histtype == 'barstacked' and not stacked:
stacked = True

# basic input validation
input_empty = np.size(x) == 0
# Massage 'x' for processing.
x = cbook._reshape_2D(x, 'x')
nx = len(x) # number of datasets
Expand All @@ -6581,9 +6579,13 @@ def hist(self, x, bins=None, range=None, density=False, weights=None,
if len(w) != nx:
raise ValueError('weights should have the same shape as x')

input_empty = True
for xi, wi in zip(x, w):
if wi is not None and len(wi) != len(xi):
len_xi = len(xi)
if wi is not None and len(wi) != len_xi:
raise ValueError('weights should have the same shape as x')
if len_xi:
input_empty = False

if color is None:
color = [self._get_lines.get_next_color() for i in range(nx)]
Expand Down
64 changes: 50 additions & 14 deletions lib/matplotlib/cbook/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -989,7 +989,12 @@ def _combine_masks(*args):
else:
if isinstance(x, np.ma.MaskedArray) and x.ndim > 1:
raise ValueError("Masked arrays must be 1-D")
x = np.asanyarray(x)
try:
x = np.asanyarray(x)
except (np.VisibleDeprecationWarning, ValueError):
# NumPy 1.19 raises a warning about ragged arrays, but we want
# to accept basically anything here.
x = np.asanyarray(x, dtype=object)
if x.ndim == 1:
x = safe_masked_invalid(x)
seqlist[i] = True
Expand Down Expand Up @@ -1316,24 +1321,48 @@ def _reshape_2D(X, name):
Use Fortran ordering to convert ndarrays and lists of iterables to lists of
1D arrays.

Lists of iterables are converted by applying `np.asarray` to each of their
elements. 1D ndarrays are returned in a singleton list containing them.
2D ndarrays are converted to the list of their *columns*.
Lists of iterables are converted by applying `np.asanyarray` to each of
their elements. 1D ndarrays are returned in a singleton list containing
them. 2D ndarrays are converted to the list of their *columns*.

*name* is used to generate the error message for invalid inputs.
"""
# Iterate over columns for ndarrays, over rows otherwise.
X = np.atleast_1d(X.T if isinstance(X, np.ndarray) else np.asarray(X))
# Iterate over columns for ndarrays.
if isinstance(X, np.ndarray):
X = X.T

if len(X) == 0:
return [[]]
elif X.ndim == 1 and np.ndim(X[0]) == 0:
# 1D array of scalars: directly return it.
return [X]
elif X.ndim in [1, 2]:
# 2D array, or 1D array of iterables: flatten them first.
return [np.reshape(x, -1) for x in X]
else:
raise ValueError(f'{name} must have 2 or fewer dimensions')

# Iterate over list of iterables.
if len(X) == 0:
return [[]]
elif X.ndim == 1 and np.ndim(X[0]) == 0:

result = []
is_1d = True
for xi in X:
xi = np.asanyarray(xi)
nd = np.ndim(xi)
if nd > 1:
raise ValueError(f'{name} must have 2 or fewer dimensions')
elif nd == 1 and len(xi) != 1:
is_1d = False
result.append(xi.reshape(-1))

if is_1d:
# 1D array of scalars: directly return it.
return [X]
elif X.ndim in [1, 2]:
# 2D array, or 1D array of iterables: flatten them first.
return [np.reshape(x, -1) for x in X]
return [np.reshape(result, -1)]
else:
raise ValueError("{} must have 2 or fewer dimensions".format(name))
# 2D array, or 1D array of iterables: use flattened version.
return result


def violin_stats(X, method, points=100, quantiles=None):
Expand Down Expand Up @@ -1399,10 +1428,10 @@ def violin_stats(X, method, points=100, quantiles=None):
quantiles = _reshape_2D(quantiles, "quantiles")
# Else, mock quantiles if is none or empty
else:
quantiles = [[]] * np.shape(X)[0]
quantiles = [[]] * len(X)

# quantiles should has the same size as dataset
if np.shape(X)[:1] != np.shape(quantiles)[:1]:
if len(X) != len(quantiles):
raise ValueError("List of violinplot statistics and quantiles values"
" must have the same length")

Expand Down Expand Up @@ -1577,8 +1606,15 @@ def index_of(y):
try:
return y.index.values, y.values
except AttributeError:
pass
try:
y = _check_1d(y)
except (np.VisibleDeprecationWarning, ValueError):
# NumPy 1.19 will warn on ragged input, and we can't actually use it.
pass
else:
return np.arange(y.shape[0], dtype=float), y
raise ValueError('Input could not be cast to an at-least-1D NumPy array')


def safe_first_element(obj):
Expand Down
3 changes: 2 additions & 1 deletion lib/matplotlib/tests/test_backend_svg.py
Original file line number Diff line number Diff line change
Expand Up @@ -191,7 +191,8 @@ def include(gid, obj):
elif obj.axes is None:
return False
if isinstance(obj, plt.Line2D):
if np.array(obj.get_data()).shape == (2, 1):
xdata, ydata = obj.get_data()
if len(xdata) == len(ydata) == 1:
return False
elif not hasattr(obj, "axes") or obj.axes is None:
return False
Expand Down
2 changes: 1 addition & 1 deletion lib/mpl_toolkits/mplot3d/art3d.py
Original file line number Diff line number Diff line change
Expand Up @@ -257,7 +257,7 @@ def set_segments(self, segments):
"""
Set 3D segments.
"""
self._segments3d = np.asanyarray(segments)
self._segments3d = segments
LineCollection.set_segments(self, [])

def do_3d_projection(self, renderer):
Expand Down