Skip to content

Commit c7da07d

Browse files
committed
Merge pull request #1724 from neggert/hist_stack_round2
Re-write stacked step histogram
2 parents c3ec92e + 9a83e9f commit c7da07d

21 files changed

+3525
-50
lines changed

lib/matplotlib/axes.py

Lines changed: 42 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -4792,11 +4792,10 @@ def make_iterable(x):
47924792
if orientation == 'vertical':
47934793
self._process_unit_info(xdata=left, ydata=height, kwargs=kwargs)
47944794
if log:
4795-
self.set_yscale('log')
4795+
self.set_yscale('log', nonposy='clip')
47964796
# size width and bottom according to length of left
47974797
if _bottom is None:
47984798
if self.get_yscale() == 'log':
4799-
bottom = [1e-100]
48004799
adjust_ylim = True
48014800
else:
48024801
bottom = [0]
@@ -4808,11 +4807,10 @@ def make_iterable(x):
48084807
elif orientation == 'horizontal':
48094808
self._process_unit_info(xdata=width, ydata=bottom, kwargs=kwargs)
48104809
if log:
4811-
self.set_xscale('log')
4810+
self.set_xscale('log', nonposx='clip')
48124811
# size left and height according to length of bottom
48134812
if _left is None:
48144813
if self.get_xscale() == 'log':
4815-
left = [1e-100]
48164814
adjust_xlim = True
48174815
else:
48184816
left = [0]
@@ -8108,10 +8106,8 @@ def hist(self, x, bins=10, range=None, normed=False, weights=None,
81088106
hist_kwargs['new'] = True
81098107

81108108
n = []
8111-
mlast = None
8112-
# reversed order is necessary so when stacking histogram, first dataset is on top
8113-
# if histogram isn't stacked, this doesn't make any difference
8114-
for i in reversed(xrange(nx)):
8109+
mlast = bottom
8110+
for i in xrange(nx):
81158111
# this will automatically overwrite bins,
81168112
# so that each histogram uses the same bins
81178113
m, bins = np.histogram(x[i], bins, weights=w[i], **hist_kwargs)
@@ -8137,8 +8133,6 @@ def hist(self, x, bins=10, range=None, normed=False, weights=None,
81378133
else:
81388134
n = [m[slc].cumsum()[slc] for m in n]
81398135

8140-
n.reverse() # put them back in the right order
8141-
81428136
patches = []
81438137

81448138
if histtype.startswith('bar'):
@@ -8175,24 +8169,34 @@ def hist(self, x, bins=10, range=None, normed=False, weights=None,
81758169
_barfunc = self.bar
81768170

81778171
for m, c in zip(n, color):
8178-
patch = _barfunc(bins[:-1]+boffset, m, width,
8172+
if bottom is None:
8173+
bottom = np.zeros(len(m), np.float)
8174+
if stacked:
8175+
height = m - bottom
8176+
else :
8177+
height = m
8178+
patch = _barfunc(bins[:-1]+boffset, height, width,
81798179
align='center', log=log,
81808180
color=c, bottom=bottom)
81818181
patches.append(patch)
8182+
if stacked:
8183+
bottom[:] = m
81828184
boffset += dw
81838185

81848186
elif histtype.startswith('step'):
8185-
x = np.zeros( 2*len(bins), np.float )
8186-
y = np.zeros( 2*len(bins), np.float )
8187+
# these define the perimeter of the polygon
8188+
x = np.zeros( 4*len(bins)-3, np.float )
8189+
y = np.zeros( 4*len(bins)-3, np.float )
81878190

8188-
x[0::2], x[1::2] = bins, bins
8191+
x[0:2*len(bins)-1:2], x[1:2*len(bins)-1:2] = bins, bins[:-1]
8192+
x[2*len(bins)-1:] = x[1:2*len(bins)-1][::-1]
81898193

81908194
if log:
81918195
if orientation == 'horizontal':
8192-
self.set_xscale('log')
8196+
self.set_xscale('log', nonposx = 'clip')
81938197
logbase = self.xaxis._scale.base
81948198
else: # orientation == 'vertical'
8195-
self.set_yscale('log')
8199+
self.set_yscale('log', nonposy = 'clip')
81968200
logbase = self.yaxis._scale.base
81978201

81988202
# Setting a minimum of 0 results in problems for log plots
@@ -8219,19 +8223,37 @@ def hist(self, x, bins=10, range=None, normed=False, weights=None,
82198223
# overriding this
82208224
fill = (histtype == 'stepfilled')
82218225

8222-
for m, c in zip(n, color):
8223-
y[1:-1:2], y[2::2] = m, m
8226+
xvals, yvals = [], []
8227+
for m in n:
8228+
# starting point for drawing polygon
8229+
y[0] = y[-1]
8230+
# top of the previous polygon becomes the bottom
8231+
y[2*len(bins)-1:] = y[1:2*len(bins)-1][::-1]
8232+
# set the top of this polygon
8233+
y[1:2*len(bins)-1:2], y[2:2*len(bins):2] = m, m
82248234
if log:
82258235
y[y<minimum]=minimum
82268236
if orientation == 'horizontal':
82278237
x,y = y,x
82288238

8239+
xvals.append(x.copy())
8240+
yvals.append(y.copy())
8241+
8242+
# add patches in reverse order so that when stacking,
8243+
# items lower in the stack are plottted on top of
8244+
# items higher in the stack
8245+
for x, y, c in reversed(zip(xvals, yvals, color)):
82298246
if fill:
82308247
patches.append( self.fill(x, y,
8231-
closed=False, facecolor=c) )
8248+
closed=False,
8249+
facecolor=c) )
82328250
else:
82338251
patches.append( self.fill(x, y,
8234-
closed=False, edgecolor=c, fill=False) )
8252+
closed=False, edgecolor=c,
8253+
fill=False) )
8254+
8255+
# we return patches, so put it back in the expected order
8256+
patches.reverse()
82358257

82368258
# adopted from adjust_x/ylim part of the bar method
82378259
if orientation == 'horizontal':
Binary file not shown.
Binary file not shown.

0 commit comments

Comments
 (0)