diff --git a/lib/matplotlib/axes/_axes.py b/lib/matplotlib/axes/_axes.py index 6b53165ca296..429c77f8b24d 100644 --- a/lib/matplotlib/axes/_axes.py +++ b/lib/matplotlib/axes/_axes.py @@ -6105,13 +6105,6 @@ def hist(self, x, bins=None, range=None, density=None, weights=None, -------- hist2d : 2D histograms - Notes - ----- - Until numpy release 1.5, the underlying numpy histogram function was - incorrect with ``normed=True`` if bin sizes were unequal. MPL - inherited that error. It is now corrected within MPL when using - earlier numpy versions. - """ # Avoid shadowing the builtin. bin_range = range @@ -6204,8 +6197,10 @@ def hist(self, x, bins=None, range=None, density=None, weights=None, else: hist_kwargs = dict(range=bin_range) - n = [] + # List to store all the top coordinates of the histograms + tops = [] mlast = None + # Loop through datasets for i in xrange(nx): # this will automatically overwrite bins, # so that each histogram uses the same bins @@ -6213,29 +6208,26 @@ def hist(self, x, bins=None, range=None, density=None, weights=None, m = m.astype(float) # causes problems later if it's an int if mlast is None: mlast = np.zeros(len(bins)-1, m.dtype) - if density and not stacked: - db = np.diff(bins) - m = (m.astype(float) / db) / m.sum() if stacked: - if mlast is None: - mlast = np.zeros(len(bins)-1, m.dtype) m += mlast mlast[:] = m - n.append(m) + tops.append(m) + # If a stacked density plot, normalize so the area of all the stacked + # histograms together is 1 if stacked and density: db = np.diff(bins) - for m in n: - m[:] = (m.astype(float) / db) / n[-1].sum() + for m in tops: + m[:] = (m.astype(float) / db) / tops[-1].sum() if cumulative: slc = slice(None) if cbook.is_numlike(cumulative) and cumulative < 0: slc = slice(None, None, -1) if density: - n = [(m * np.diff(bins))[slc].cumsum()[slc] for m in n] + tops = [(m * np.diff(bins))[slc].cumsum()[slc] for m in tops] else: - n = [m[slc].cumsum()[slc] for m in n] + tops = [m[slc].cumsum()[slc] for m in tops] patches = [] @@ -6253,7 +6245,7 @@ def hist(self, x, bins=None, range=None, density=None, weights=None, if rwidth is not None: dr = np.clip(rwidth, 0, 1) - elif (len(n) > 1 and + elif (len(tops) > 1 and ((not stacked) or rcParams['_internal.classic_mode'])): dr = 0.8 else: @@ -6279,7 +6271,7 @@ def hist(self, x, bins=None, range=None, density=None, weights=None, _barfunc = self.bar bottom_kwarg = 'bottom' - for m, c in zip(n, color): + for m, c in zip(tops, color): if bottom is None: bottom = np.zeros(len(m)) if stacked: @@ -6323,7 +6315,7 @@ def hist(self, x, bins=None, range=None, density=None, weights=None, # For data that is normed to form a probability density, # set to minimum data value / logbase # (gives 1 full tick-label unit for the lowest filled bin) - ndata = np.array(n) + ndata = np.array(tops) minimum = (np.min(ndata[ndata > 0])) / logbase else: # For non-normed (density = False) data, @@ -6346,7 +6338,7 @@ def hist(self, x, bins=None, range=None, density=None, weights=None, fill = (histtype == 'stepfilled') xvals, yvals = [], [] - for m in n: + for m in tops: if stacked: # starting point for drawing polygon y[0] = y[1] @@ -6409,9 +6401,9 @@ def hist(self, x, bins=None, range=None, density=None, weights=None, p.set_label('_nolegend_') if nx == 1: - return n[0], bins, cbook.silent_list('Patch', patches[0]) + return tops[0], bins, cbook.silent_list('Patch', patches[0]) else: - return n, bins, cbook.silent_list('Lists of Patches', patches) + return tops, bins, cbook.silent_list('Lists of Patches', patches) @_preprocess_data(replace_names=["x", "y", "weights"], label_namer=None) def hist2d(self, x, y, bins=10, range=None, normed=False, weights=None, diff --git a/lib/matplotlib/tests/baseline_images/test_axes/hist_density.png b/lib/matplotlib/tests/baseline_images/test_axes/hist_density.png new file mode 100644 index 000000000000..d75fc1fd8849 Binary files /dev/null and b/lib/matplotlib/tests/baseline_images/test_axes/hist_density.png differ diff --git a/lib/matplotlib/tests/test_axes.py b/lib/matplotlib/tests/test_axes.py index ab1f013be9f4..d24f52061299 100644 --- a/lib/matplotlib/tests/test_axes.py +++ b/lib/matplotlib/tests/test_axes.py @@ -1493,6 +1493,14 @@ def test_hist_step_filled(): assert all([p.get_facecolor() == p.get_edgecolor() for p in patches]) +@image_comparison(baseline_images=['hist_density'], extensions=['png']) +def test_hist_density(): + np.random.seed(19680801) + data = np.random.standard_normal(2000) + fig, ax = plt.subplots() + ax.hist(data, density=True) + + @image_comparison(baseline_images=['hist_step_log_bottom'], remove_text=True, extensions=['png']) def test_hist_step_log_bottom():