diff --git a/lib/matplotlib/axes.py b/lib/matplotlib/axes.py index d50928e60466..db671e7967c2 100644 --- a/lib/matplotlib/axes.py +++ b/lib/matplotlib/axes.py @@ -8245,6 +8245,17 @@ def hist(self, x, bins=10, range=None, normed=False, weights=None, if histtype == 'barstacked' and not stacked: stacked = True + # Check whether bins or range are given explicitly. + binsgiven = (cbook.iterable(bins) or bin_range is not None) + + # basic input validation + flat = np.ravel(x) + if len(flat) == 0: + raise ValueError("x must have at least one data point") + elif len(flat) == 1 and not binsgiven: + raise ValueError( + "x has only one data point. bins or range kwarg must be given") + # Massage 'x' for processing. # NOTE: Be sure any changes here is also done below to 'weights' if isinstance(x, np.ndarray) or not iterable(x[0]): @@ -8299,10 +8310,6 @@ def hist(self, x, bins=10, range=None, normed=False, weights=None, # Save the datalimits for the same reason: _saved_bounds = self.dataLim.bounds - # Check whether bins or range are given explicitly. In that - # case use those values for autoscaling. - binsgiven = (cbook.iterable(bins) or bin_range is not None) - # If bins are not specified either explicitly or via range, # we need to figure out the range required for all datasets, # and supply that to np.histogram. @@ -8310,8 +8317,9 @@ def hist(self, x, bins=10, range=None, normed=False, weights=None, xmin = np.inf xmax = -np.inf for xi in x: - xmin = min(xmin, xi.min()) - xmax = max(xmax, xi.max()) + if len(xi) > 0: + xmin = min(xmin, xi.min()) + xmax = max(xmax, xi.max()) bin_range = (xmin, xmax) #hist_kwargs = dict(range=range, normed=bool(normed)) @@ -8503,7 +8511,8 @@ def hist(self, x, bins=10, range=None, normed=False, weights=None, xmin0 = max(_saved_bounds[0]*0.9, minimum) xmax = self.dataLim.intervalx[1] for m in n: - xmin = np.amin(m[m != 0]) # filter out the 0 height bins + if np.sum(m) > 0: # make sure there are counts + xmin = np.amin(m[m != 0]) # filter out the 0 height bins xmin = max(xmin*0.9, minimum) xmin = min(xmin0, xmin) self.dataLim.intervalx = (xmin, xmax) @@ -8511,7 +8520,8 @@ def hist(self, x, bins=10, range=None, normed=False, weights=None, ymin0 = max(_saved_bounds[1]*0.9, minimum) ymax = self.dataLim.intervaly[1] for m in n: - ymin = np.amin(m[m != 0]) # filter out the 0 height bins + if np.sum(m) > 0: # make sure there are counts + ymin = np.amin(m[m != 0]) # filter out the 0 height bins ymin = max(ymin*0.9, minimum) ymin = min(ymin0, ymin) self.dataLim.intervaly = (ymin, ymax) diff --git a/lib/matplotlib/tests/test_axes.py b/lib/matplotlib/tests/test_axes.py index 4b166bcd5c94..3919c7bd034b 100644 --- a/lib/matplotlib/tests/test_axes.py +++ b/lib/matplotlib/tests/test_axes.py @@ -1162,6 +1162,12 @@ def test_hist_stacked_bar(): ax.hist(d, bins=10, histtype='barstacked', align='mid', color=colors, label=labels) ax.legend(loc='upper right', bbox_to_anchor = (1.0, 1.0), ncol=1) +@cleanup +def test_hist_emptydata(): + fig = plt.figure() + ax = fig.add_subplot(111) + ax.hist([[], range(10), range(10)], histtype="step") + @image_comparison(baseline_images=['transparent_markers'], remove_text=True) def test_transparent_markers(): np.random.seed(0)