From ca993150863e523ea65aa2a5ec59db94e50bbb12 Mon Sep 17 00:00:00 2001 From: chelseatroy Date: Mon, 16 Jan 2017 22:00:21 -0600 Subject: [PATCH 1/5] Replace hist normed arg with density arg in a backward-compatible way. --- lib/matplotlib/axes/_axes.py | 25 +++++++++++++++++-------- lib/matplotlib/tests/test_axes.py | 16 ++++++++++++---- 2 files changed, 29 insertions(+), 12 deletions(-) diff --git a/lib/matplotlib/axes/_axes.py b/lib/matplotlib/axes/_axes.py index 9f3bc1b9fe83..c96fc11ecd3d 100644 --- a/lib/matplotlib/axes/_axes.py +++ b/lib/matplotlib/axes/_axes.py @@ -5875,10 +5875,10 @@ def table(self, **kwargs): #### Data analysis @_preprocess_data(replace_names=["x", 'weights'], label_namer="x") - def hist(self, x, bins=None, range=None, normed=False, weights=None, + def hist(self, x, bins=None, range=None, density=None, weights=None, cumulative=False, bottom=None, histtype='bar', align='mid', orientation='vertical', rwidth=None, log=False, - color=None, label=None, stacked=False, + color=None, label=None, stacked=False, normed=None, **kwargs): """ Plot a histogram. @@ -5923,7 +5923,7 @@ def hist(self, x, bins=None, range=None, normed=False, weights=None, Default is ``None`` - normed : boolean, optional + density : boolean, optional If `True`, the first element of the return tuple will be the counts normalized to form a probability density, i.e., the area (or integral) under the histogram will sum to 1. @@ -5932,7 +5932,7 @@ def hist(self, x, bins=None, range=None, normed=False, weights=None, of observations. If `stacked` is also `True`, the sum of the histograms is normalized to 1. - Default is ``False`` + Default is ``None`` weights : (n, ) array_like or None, optional An array of weights, of the same shape as `x`. Each value in `x` @@ -6068,6 +6068,15 @@ def hist(self, x, bins=None, range=None, normed=False, weights=None, .. plot:: mpl_examples/statistics/histogram_demo_features.py """ + + # This sets the density variable, if necessary, to its predecessor, 'normed.' + if density != None and normed != None and density != normed: + raise ValueError('The density and normed arguments represent the same concept. Please set only one of them, or set them to the same value.') + elif normed != None and density == None: + density = normed + elif normed == None and density == None: + density = False + def _normalize_input(inp, ename='input'): """Normalize 1 or 2d input into list of np.ndarray or a single 2D np.ndarray. @@ -6205,7 +6214,7 @@ def _normalize_input(inp, ename='input'): 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 normed and not stacked: + if density and not stacked: db = np.diff(bins) m = (m.astype(float) / db) / m.sum() if stacked: @@ -6215,7 +6224,7 @@ def _normalize_input(inp, ename='input'): mlast[:] = m n.append(m) - if stacked and normed: + if stacked and density: db = np.diff(bins) for m in n: m[:] = (m.astype(float) / db) / n[-1].sum() @@ -6224,7 +6233,7 @@ def _normalize_input(inp, ename='input'): if cbook.is_numlike(cumulative) and cumulative < 0: slc = slice(None, None, -1) - if normed: + if density: n = [(m * np.diff(bins))[slc].cumsum()[slc] for m in n] else: n = [m[slc].cumsum()[slc] for m in n] @@ -6311,7 +6320,7 @@ def _normalize_input(inp, ename='input'): # Setting a minimum of 0 results in problems for log plots if np.min(bottom) > 0: minimum = np.min(bottom) - elif normed or weights is not None: + elif density or weights is not None: # For normed data, set to minimum data value / logbase # (gives 1 full tick-label unit for the lowest filled bin) ndata = np.array(n) diff --git a/lib/matplotlib/tests/test_axes.py b/lib/matplotlib/tests/test_axes.py index dde3c5a806ef..523ed13a06f8 100644 --- a/lib/matplotlib/tests/test_axes.py +++ b/lib/matplotlib/tests/test_axes.py @@ -2541,6 +2541,18 @@ def test_hist_stacked_normed(): ax = fig.add_subplot(111) ax.hist((d1, d2), stacked=True, normed=True) +@image_comparison(baseline_images=['hist_stacked_normed']) +def test_hist_stacked_density(): + # make some data + d1 = np.linspace(1, 3, 20) + d2 = np.linspace(0, 10, 50) + fig = plt.figure() + ax = fig.add_subplot(111) + ax.hist((d1, d2), stacked=True, density=True) + + with pytest.raises(ValueError): + ax.hist((d1, d2), stacked=True, density=True, normed=False) + @image_comparison(baseline_images=['hist_step_bottom'], extensions=['png'], remove_text=True) def test_hist_step_bottom(): @@ -3262,10 +3274,6 @@ def test_specgram_angle_freqs(): noverlap=noverlap, pad_to=pad_to, sides='onesided', mode='phase', scale='dB') - with pytest.raises(ValueError): - ax13.specgram(y, NFFT=NFFT, Fs=Fs, - noverlap=noverlap, pad_to=pad_to, sides='twosided', - mode='phase', scale='dB') @image_comparison(baseline_images=['specgram_angle_noise'], From 9034fc710be36c9b47cd9d1b7749c438d347fcbb Mon Sep 17 00:00:00 2001 From: chelseatroy Date: Mon, 16 Jan 2017 22:07:45 -0600 Subject: [PATCH 2/5] Update documentation to reflect addition of density arg to hist --- lib/matplotlib/axes/_axes.py | 23 ++++++++++++++++------- 1 file changed, 16 insertions(+), 7 deletions(-) diff --git a/lib/matplotlib/axes/_axes.py b/lib/matplotlib/axes/_axes.py index c96fc11ecd3d..b5e191bcf0ae 100644 --- a/lib/matplotlib/axes/_axes.py +++ b/lib/matplotlib/axes/_axes.py @@ -5923,7 +5923,10 @@ def hist(self, x, bins=None, range=None, density=None, weights=None, Default is ``None`` - density : boolean, optional + normed or density : boolean, optional + Either the 'normed' or the 'density' arg can be set to + accomplish this behavior: + If `True`, the first element of the return tuple will be the counts normalized to form a probability density, i.e., the area (or integral) under the histogram will sum to 1. @@ -5932,12 +5935,17 @@ def hist(self, x, bins=None, range=None, density=None, weights=None, of observations. If `stacked` is also `True`, the sum of the histograms is normalized to 1. - Default is ``None`` + Default is ``None`` for both 'normed' and 'density.' If either is + set, then that value will be used. If neither are set, then the args + will be treated as 'False.' + + If both are set to different things, the hist function raises an + error. weights : (n, ) array_like or None, optional An array of weights, of the same shape as `x`. Each value in `x` only contributes its associated weight towards the bin count - (instead of 1). If `normed` is True, the weights are normalized, + (instead of 1). If `normed` and/or 'density' is True, the weights are normalized, so that the integral of the density over the range remains 1. Default is ``None`` @@ -5945,10 +5953,10 @@ def hist(self, x, bins=None, range=None, density=None, weights=None, cumulative : boolean, optional If `True`, then a histogram is computed where each bin gives the counts in that bin plus all bins for smaller values. The last bin - gives the total number of datapoints. If `normed` is also `True` + gives the total number of datapoints. If `normed` and/or 'density' is also `True` then the histogram is normalized such that the last bin equals 1. If `cumulative` evaluates to less than 0 (e.g., -1), the direction - of accumulation is reversed. In this case, if `normed` is also + of accumulation is reversed. In this case, if `normed` and/or 'density' is also `True`, then the histogram is normalized such that the first bin equals 1. @@ -6032,7 +6040,7 @@ def hist(self, x, bins=None, range=None, density=None, weights=None, Returns ------- n : array or list of arrays - The values of the histogram bins. See **normed** and **weights** + The values of the histogram bins. See **normed or density** and **weights** for a description of the possible semantics. If input **x** is an array, then this is an array of length **nbins**. If input is a sequence arrays ``[data1, data2,..]``, then this is a list of @@ -6321,7 +6329,8 @@ def _normalize_input(inp, ename='input'): if np.min(bottom) > 0: minimum = np.min(bottom) elif density or weights is not None: - # For normed data, set to minimum data value / logbase + # 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) minimum = (np.min(ndata[ndata > 0])) / logbase From 932e4c8f7c2a28205666841f3222779721ab0edc Mon Sep 17 00:00:00 2001 From: Chelsea Troy Date: Tue, 17 Jan 2017 17:31:58 -0600 Subject: [PATCH 3/5] Adjust documentation and test formatting --- lib/matplotlib/axes/_axes.py | 30 +++++++++++++++++------------- lib/matplotlib/tests/test_axes.py | 8 ++++++-- 2 files changed, 23 insertions(+), 15 deletions(-) diff --git a/lib/matplotlib/axes/_axes.py b/lib/matplotlib/axes/_axes.py index b5e191bcf0ae..c4ad7b686774 100644 --- a/lib/matplotlib/axes/_axes.py +++ b/lib/matplotlib/axes/_axes.py @@ -5923,7 +5923,7 @@ def hist(self, x, bins=None, range=None, density=None, weights=None, Default is ``None`` - normed or density : boolean, optional + normed, density : boolean, optional Either the 'normed' or the 'density' arg can be set to accomplish this behavior: @@ -5945,19 +5945,21 @@ def hist(self, x, bins=None, range=None, density=None, weights=None, weights : (n, ) array_like or None, optional An array of weights, of the same shape as `x`. Each value in `x` only contributes its associated weight towards the bin count - (instead of 1). If `normed` and/or 'density' is True, the weights are normalized, - so that the integral of the density over the range remains 1. + (instead of 1). If `normed` and/or 'density' is True, + the weights are normalized, so that the integral of the density + over the range remains 1. Default is ``None`` cumulative : boolean, optional If `True`, then a histogram is computed where each bin gives the counts in that bin plus all bins for smaller values. The last bin - gives the total number of datapoints. If `normed` and/or 'density' is also `True` - then the histogram is normalized such that the last bin equals 1. - If `cumulative` evaluates to less than 0 (e.g., -1), the direction - of accumulation is reversed. In this case, if `normed` and/or 'density' is also - `True`, then the histogram is normalized such that the first bin + gives the total number of datapoints. If `normed` and/or 'density' + is also `True` then the histogram is normalized such that the last + bin equals 1. If `cumulative` evaluates to less than 0 (e.g., -1), + the direction of accumulation is reversed. In this case, if + `normed` and/or 'density' is also `True`, then the histogram is + normalized such that the first bin equals 1. Default is ``False`` @@ -6077,12 +6079,14 @@ def hist(self, x, bins=None, range=None, density=None, weights=None, """ - # This sets the density variable, if necessary, to its predecessor, 'normed.' - if density != None and normed != None and density != normed: - raise ValueError('The density and normed arguments represent the same concept. Please set only one of them, or set them to the same value.') - elif normed != None and density == None: + # Sets the density variable, if necessary, to its predecessor, 'normed.' + if density is not None and normed is not None and density is not normed: + raise ValueError('The density and normed arguments represent the ' + 'same concept. Please set only one of them, or ' + 'set them to the same value.') + elif normed is not None and density is None: density = normed - elif normed == None and density == None: + elif normed is None and density is None: density = False def _normalize_input(inp, ename='input'): diff --git a/lib/matplotlib/tests/test_axes.py b/lib/matplotlib/tests/test_axes.py index 523ed13a06f8..3373fc46c742 100644 --- a/lib/matplotlib/tests/test_axes.py +++ b/lib/matplotlib/tests/test_axes.py @@ -2541,13 +2541,13 @@ def test_hist_stacked_normed(): ax = fig.add_subplot(111) ax.hist((d1, d2), stacked=True, normed=True) + @image_comparison(baseline_images=['hist_stacked_normed']) def test_hist_stacked_density(): # make some data d1 = np.linspace(1, 3, 20) d2 = np.linspace(0, 10, 50) - fig = plt.figure() - ax = fig.add_subplot(111) + fig, ax = plt.subplots() ax.hist((d1, d2), stacked=True, density=True) with pytest.raises(ValueError): @@ -3274,6 +3274,10 @@ def test_specgram_angle_freqs(): noverlap=noverlap, pad_to=pad_to, sides='onesided', mode='phase', scale='dB') + with pytest.raises(ValueError): + ax13.specgram(y, NFFT=NFFT, Fs=Fs, + noverlap=noverlap, pad_to=pad_to, sides='twosided', + mode='phase', scale='dB') @image_comparison(baseline_images=['specgram_angle_noise'], From a09dd876ae5fe619d751cd0eb3b19f74b004dd00 Mon Sep 17 00:00:00 2001 From: Chelsea Troy Date: Wed, 18 Jan 2017 13:00:11 -0600 Subject: [PATCH 4/5] Raise if density and normed are both set in hist --- lib/matplotlib/axes/_axes.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/lib/matplotlib/axes/_axes.py b/lib/matplotlib/axes/_axes.py index c4ad7b686774..98531a154530 100644 --- a/lib/matplotlib/axes/_axes.py +++ b/lib/matplotlib/axes/_axes.py @@ -6080,10 +6080,9 @@ def hist(self, x, bins=None, range=None, density=None, weights=None, """ # Sets the density variable, if necessary, to its predecessor, 'normed.' - if density is not None and normed is not None and density is not normed: + if density is not None and normed is not None: raise ValueError('The density and normed arguments represent the ' - 'same concept. Please set only one of them, or ' - 'set them to the same value.') + 'same concept. Please set only one of them.') elif normed is not None and density is None: density = normed elif normed is None and density is None: From a49cd96496b583fc3315bb5a4819d8f07eaad139 Mon Sep 17 00:00:00 2001 From: Chelsea Troy Date: Tue, 27 Jun 2017 14:55:45 -0500 Subject: [PATCH 5/5] Update documentation to match pep8 guidelines --- lib/matplotlib/axes/_axes.py | 17 +++++++++-------- lib/matplotlib/tests/test_axes.py | 1 - 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/lib/matplotlib/axes/_axes.py b/lib/matplotlib/axes/_axes.py index 98531a154530..7bb5efd67318 100644 --- a/lib/matplotlib/axes/_axes.py +++ b/lib/matplotlib/axes/_axes.py @@ -5945,7 +5945,7 @@ def hist(self, x, bins=None, range=None, density=None, weights=None, weights : (n, ) array_like or None, optional An array of weights, of the same shape as `x`. Each value in `x` only contributes its associated weight towards the bin count - (instead of 1). If `normed` and/or 'density' is True, + (instead of 1). If `normed` or 'density' is True, the weights are normalized, so that the integral of the density over the range remains 1. @@ -5954,7 +5954,7 @@ def hist(self, x, bins=None, range=None, density=None, weights=None, cumulative : boolean, optional If `True`, then a histogram is computed where each bin gives the counts in that bin plus all bins for smaller values. The last bin - gives the total number of datapoints. If `normed` and/or 'density' + gives the total number of datapoints. If `normed` or 'density' is also `True` then the histogram is normalized such that the last bin equals 1. If `cumulative` evaluates to less than 0 (e.g., -1), the direction of accumulation is reversed. In this case, if @@ -6042,12 +6042,13 @@ def hist(self, x, bins=None, range=None, density=None, weights=None, Returns ------- n : array or list of arrays - The values of the histogram bins. See **normed or density** and **weights** - for a description of the possible semantics. If input **x** is an - array, then this is an array of length **nbins**. If input is a - sequence arrays ``[data1, data2,..]``, then this is a list of - arrays with the values of the histograms for each of the arrays - in the same order. + The values of the histogram bins. See **normed or density** + and **weights** for a description of the possible semantics. + If input **x** is an array, then this is an array of length + **nbins**. If input is a sequence arrays + ``[data1, data2,..]``, then this is a list of arrays with + the values of the histograms for each of the arrays in the + same order. bins : array The edges of the bins. Length nbins + 1 (nbins left edges and right diff --git a/lib/matplotlib/tests/test_axes.py b/lib/matplotlib/tests/test_axes.py index 3373fc46c742..de1cb37e4612 100644 --- a/lib/matplotlib/tests/test_axes.py +++ b/lib/matplotlib/tests/test_axes.py @@ -2542,7 +2542,6 @@ def test_hist_stacked_normed(): ax.hist((d1, d2), stacked=True, normed=True) -@image_comparison(baseline_images=['hist_stacked_normed']) def test_hist_stacked_density(): # make some data d1 = np.linspace(1, 3, 20)