8000 Merge pull request #847 from neggert/stacked_step_hist · dmcdougall/matplotlib@634f02d · GitHub
[go: up one dir, main page]

Skip to content

Commit 634f02d

Browse files
committed
Merge pull request matplotlib#847 from neggert/stacked_step_hist
Add stacked kwarg to hist and implement stacked hists for step histtype
2 parents b55923b + 242ecac commit 634f02d

File tree

8 files changed

+619
-13
lines changed

8 files changed

+619
-13
lines changed

doc/users/whats_new.rst

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -163,6 +163,17 @@ local intensity of the vector field.
163163

164164
.. plot:: mpl_examples/pylab_examples/streamplot_demo.py
165165

166+
167+
New hist functionality
168+
----------------------
169+
170+
Nic Eggert added a new `stacked` kwarg to :meth:`~matplotlib.pyplot.hist` that
171+
allows creation of stacked histograms using any of the histogram types.
172+
Previously, this functionality was only available by using the `barstacked`
173+
histogram type. Now, when `stacked=True` is passed to the function, any of the
174+
histogram types can be stacked. The `barstacked` histogram type retains its
175+
previous functionality for backwards compatibility.
176+
166177
Updated shipped dependencies
167178
----------------------------
168179

examples/pylab_examples/histogram_demo_extended.py

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,19 @@
8282
#
8383
P.figure()
8484

85-
n, bins, patches = P.hist(x, 10, normed=1, histtype='barstacked')
85+
n, bins, patches = P.hist(x, 10, normed=1, histtype='bar', stacked=True)
86+
87+
P.show()
88+
89+
#
90+
# we can also stack using the step histtype
91+
#
92+
93+
P.figure()
94+
95+
n, bins, patches = P.hist(x, 10, histtype='step', stacked=True, fill=True)
96+
97+
P.show()
8698

8799
#
88100
# finally: make a multiple-histogram of data-sets with different length

lib/matplotlib/axes.py

Lines changed: 26 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -7779,7 +7779,7 @@ def get_shared_y_axes(self):
77797779
def hist(self, x, bins=10, range=None, normed=False, weights=None,
77807780
cumulative=False, bottom=None, histtype='bar', align='mid',
77817781
orientation='vertical', rwidth=None, log=False,
7782-
color=None, label=None,
7782+
color=None, label=None, stacked=False,
77837783
**kwargs):
77847784
"""
77857785
Plot a histogram.
@@ -7789,7 +7789,7 @@ def hist(self, x, bins=10, range=None, normed=False, weights=None,
77897789
hist(x, bins=10, range=None, normed=False, weights=None,
77907790
cumulative=False, bottom=None, histtype='bar', align='mid',
77917791
orientation='vertical', rwidth=None, log=False,
7792-
color=None, label=None,
7792+
color=None, label=None, stacked=False,
77937793
**kwargs)
77947794
77957795
Compute and draw the histogram of *x*. The return value is a
@@ -7913,6 +7913,11 @@ def hist(self, x, bins=10, range=None, normed=False, weights=None,
79137913
ax.hist(12+3*np.random.randn(1000), label='women', alpha=0.5)
79147914
ax.legend()
79157915
7916+
*stacked*:
7917+
If *True*, multiple data are stacked on top of each other
7918+
If *False* multiple data are aranged side by side if
7919+
histtype is 'bar' or on top of each other if histtype is 'step'
7920+
79167921
.
79177922
79187923
kwargs are used to update the properties of the
@@ -7952,6 +7957,9 @@ def hist(self, x, bins=10, range=None, normed=False, weights=None,
79527957
'hist now uses the rwidth to give relative width '
79537958
'and not absolute width')
79547959

7960+
if histtype == 'barstacked' and not stacked:
7961+
stacked=True
7962+
79557963
# Massage 'x' for processing.
79567964
# NOTE: Be sure any changes here is also done below to 'weights'
79577965
if isinstance(x, np.ndarray) or not iterable(x[0]):
@@ -8037,13 +8045,21 @@ def hist(self, x, bins=10, range=None, normed=False, weights=None,
80378045
hist_kwargs['new'] = True
80388046

80398047
n = []
8040-
for i in xrange(nx):
8048+
mlast = bottom
8049+
# reversed order is necessary so when stacking histogram, first dataset is on top
8050+
# if histogram isn't stacked, this doesn't make any difference
8051+
for i in reversed(xrange(nx)):
80418052
# this will automatically overwrite bins,
80428053
# so that each histogram uses the same bins
80438054
m, bins = np.histogram(x[i], bins, weights=w[i], **hist_kwargs)
8055+
if mlast is None:
8056+
mlast = np.zeros(len(bins)-1, np.int)
80448057
if normed:
80458058
db = np.diff(bins)
80468059
m = (m.astype(float) / db) / m.sum()
8060+
if stacked:
8061+
m += mlast
8062+
mlast[:] = m
80478063
n.append(m)
80488064

80498065
if cumulative:
@@ -8056,6 +8072,8 @@ def hist(self, x, bins=10, range=None, normed=False, weights=None,
80568072
else:
80578073
n = [m[slc].cumsum()[slc] for m in n]
80588074

8075+
n.reverse() # put them back in the right order
8076+
80598077
patches = []
80608078

80618079
if histtype.startswith('bar'):
@@ -8068,7 +8086,7 @@ def hist(self, x, bins=10, range=None, normed=False, weights=None,
80688086
else:
80698087
dr = 1.0
80708088

8071-
if histtype=='bar':
8089+
if histtype=='bar' and not stacked:
80728090
width = dr*totwidth/nx
80738091
dw = width
80748092

@@ -8077,10 +8095,9 @@ def hist(self, x, bins=10, range=None, normed=False, weights=None,
80778095
else:
80788096
boffset = 0.0
80798097
stacked = False
8080-
elif histtype=='barstacked':
8098+
elif histtype=='barstacked' or stacked:
80818099
width = dr*totwidth
80828100
boffset, dw = 0.0, 0.0
8083-
stacked = True
80848101

80858102
if align == 'mid' or align == 'edge':
80868103
boffset += 0.5*totwidth
@@ -8093,14 +8110,10 @@ def hist(self, x, bins=10, range=None, normed=False, weights=None,
80938110
_barfunc = self.bar
80948111

80958112
for m, c in zip(n, color):
8096-
patch = _barfunc(bins[:-1]+boffset, m, width, bottom,
8113+
patch = _barfunc(bins[:-1]+boffset, m, width,
80978114
align='center', log=log,
80988115
color=c)
80998116
patches.append(patch)
8100-
if stacked:
8101-
if bottom is None:
8102-
bottom = 0.0
8103-
bottom += m
81048117
boffset += dw
81058118

81068119
elif histtype.startswith('step'):
@@ -8123,6 +8136,8 @@ def hist(self, x, bins=10, range=None, normed=False, weights=None,
81238136
else: # orientation == 'vertical'
81248137
self.set_yscale('log')
81258138

8139+
# If fill kwarg is set, it will be passed to the patch collection,
8140+
# overriding this
81268141
fill = (histtype == 'stepfilled')
81278142

81288143
for m, c in zip(n, color):

lib/matplotlib/pyplot.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2639,7 +2639,8 @@ def hexbin(x, y, C=None, gridsize=100, bins=None, xscale='linear',
26392639
@_autogen_docstring(Axes.hist)
26402640
def hist(x, bins=10, range=None, normed=False, weights=None, cumulative=False,
26412641
bottom=None, histtype='bar', align='mid', orientation='vertical',
2642-
rwidth=None, log=False, color=None, label=None, hold=None, **kwargs):
2642+
rwidth=None, log=False, color=None, label=None, stacked=False,
2643+
hold=None, **kwargs):
26432644
ax = gca()
26442645
# allow callers to override the hold state by passing hold=True|False
26452646
washold = ax.ishold()
Binary file not shown.
Loading

0 commit comments

Comments
 (0)
0