diff --git a/lib/matplotlib/axes/_axes.py b/lib/matplotlib/axes/_axes.py index 76dc174e2f53..d5f15e86f533 100644 --- a/lib/matplotlib/axes/_axes.py +++ b/lib/matplotlib/axes/_axes.py @@ -6106,41 +6106,6 @@ def hist(self, x, bins=None, range=None, normed=False, weights=None, bin_range = range del range - def _normalize_input(inp, ename='input'): - """Normalize 1 or 2d input into list of np.ndarray or - a single 2D np.ndarray. - - Parameters - ---------- - inp : iterable - ename : str, optional - Name to use in ValueError if `inp` can not be normalized - - """ - if (isinstance(x, np.ndarray) or - not iterable(cbook.safe_first_element(inp))): - # TODO: support masked arrays; - inp = np.asarray(inp) - if inp.ndim == 2: - # 2-D input with columns as datasets; switch to rows - inp = inp.T - elif inp.ndim == 1: - # new view, single row - inp = inp.reshape(1, inp.shape[0]) - else: - raise ValueError( - "{ename} must be 1D or 2D".format(ename=ename)) - if inp.shape[1] < inp.shape[0]: - warnings.warn( - '2D hist input should be nsamples x nvariables;\n ' - 'this looks transposed ' - '(shape is %d x %d)' % inp.shape[::-1]) - else: - # multiple hist with data of different length - inp = [np.asarray(xi) for xi in inp] - - return inp - if not self._hold: self.cla() @@ -6175,20 +6140,18 @@ def _normalize_input(inp, ename='input'): binsgiven = (cbook.iterable(bins) or bin_range is not None) # basic input validation - flat = np.ravel(x) - - input_empty = len(flat) == 0 + input_empty = np.size(x) == 0 # Massage 'x' for processing. if input_empty: x = np.array([[]]) else: - x = _normalize_input(x, 'x') + x = cbook._reshape_2D(x, 'x') nx = len(x) # number of datasets # We need to do to 'weights' what was done to 'x' if weights is not None: - w = _normalize_input(weights, 'weights') + w = cbook._reshape_2D(weights, 'weights') else: w = [None]*nx diff --git a/lib/matplotlib/cbook/__init__.py b/lib/matplotlib/cbook/__init__.py index 9568dfa6442f..2bec9f2be6a4 100644 --- a/lib/matplotlib/cbook/__init__.py +++ b/lib/matplotlib/cbook/__init__.py @@ -1744,7 +1744,7 @@ def _compute_conf_interval(data, med, iqr, bootstrap): bxpstats = [] # convert X to a list of lists - X = _reshape_2D(X) + X = _reshape_2D(X, "X") ncols = len(X) if labels is None: @@ -1974,14 +1974,16 @@ def _check_1d(x): return np.atleast_1d(x) -def _reshape_2D(X): +def _reshape_2D(X, name): """ - Converts a non-empty list or an ndarray of two or fewer dimensions - into a list of iterable objects so that in + Use Fortran ordering to convert ndarrays and lists of iterables to lists of + 1D arrays. - for v in _reshape_2D(X): + 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*. - v is iterable and can be used to instantiate a 1D array. + *name* is used to generate the error message for invalid inputs. """ # Iterate over columns for ndarrays, over rows otherwise. X = X.T if isinstance(X, np.ndarray) else np.asarray(X) @@ -1992,7 +1994,7 @@ def _reshape_2D(X): # 2D array, or 1D array of iterables: flatten them first. return [np.reshape(x, -1) for x in X] else: - raise ValueError("input `X` must have 2 or fewer dimensions") + raise ValueError("{} must have 2 or fewer dimensions".format(name)) def violin_stats(X, method, points=100): @@ -2039,7 +2041,7 @@ def violin_stats(X, method, points=100): vpstats = [] # Want X to be a list of data sequences - X = _reshape_2D(X) + X = _reshape_2D(X, "X") for x in X: # Dictionary of results for this distribution