From 5a2c9af561470a99ecb1eb242b00810455e85fb6 Mon Sep 17 00:00:00 2001 From: Nic Eggert Date: Sun, 27 Oct 2013 14:35:10 -0400 Subject: [PATCH 1/4] Allow empty datasets to be passed to hist, as long as at least one dataset has data --- lib/matplotlib/axes.py | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/lib/matplotlib/axes.py b/lib/matplotlib/axes.py index d50928e60466..514e6607fff7 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)) From 2786e392bfe1e6f36cd29ea0584da42c55829455 Mon Sep 17 00:00:00 2001 From: Nic Eggert Date: Sun, 27 Oct 2013 21:56:25 -0400 Subject: [PATCH 2/4] Fixed another location where empty datasets in hist caused exceptions --- lib/matplotlib/axes.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/lib/matplotlib/axes.py b/lib/matplotlib/axes.py index 514e6607fff7..db671e7967c2 100644 --- a/lib/matplotlib/axes.py +++ b/lib/matplotlib/axes.py @@ -8511,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) @@ -8519,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) From 03a960d461e8f1ff995027e12b5bdeae6bd50090 Mon Sep 17 00:00:00 2001 From: Nic Eggert Date: Mon, 6 Jan 2014 12:48:40 -0500 Subject: [PATCH 3/4] Add test for histogram with empty dataset --- lib/matplotlib/tests/test_axes.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/lib/matplotlib/tests/test_axes.py b/lib/matplotlib/tests/test_axes.py index 4b166bcd5c94..f74dd7479932 100644 --- a/lib/matplotlib/tests/test_axes.py +++ b/lib/matplotlib/tests/test_axes.py @@ -1162,6 +1162,11 @@ 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) +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) From 7a5ec9ff2b580dfd9a91b774d80e72350e44ef66 Mon Sep 17 00:00:00 2001 From: Nic Eggert Date: Fri, 10 Jan 2014 09:12:45 -0500 Subject: [PATCH 4/4] Add cleanup to test --- lib/matplotlib/tests/test_axes.py | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/matplotlib/tests/test_axes.py b/lib/matplotlib/tests/test_axes.py index f74dd7479932..3919c7bd034b 100644 --- a/lib/matplotlib/tests/test_axes.py +++ b/lib/matplotlib/tests/test_axes.py @@ -1162,6 +1162,7 @@ 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)