Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 24f537f

Browse files
Tillstendmcdougall
authored andcommitted
[ENH] added baseline feature to stacked graph.
1 parent d1e4902 commit 24f537f

1 file changed

Lines changed: 56 additions & 5 deletions

File tree

lib/matplotlib/stackplot.py

Lines changed: 56 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,16 @@ def stackplot(axes, x, *args, **kwargs):
2525
2626
Keyword arguments:
2727
28+
*baseline* : ['zero', 'sym', 'wiggle', 'weighted_wiggle']
29+
Method use to calculate to baseline. 'zero' is just a
30+
simple stacked plot. 'sym' is symmetric around zero and
31+
is sometimes called `ThemeRiver`. 'wiggle' minimizes the
32+
sum of the squared slopes. 'weighted_wiggle' does the
33+
same but weights to account for size of each layer.
34+
It is also called `Streamgraph`-layout. More details
35+
can be found in http://www.leebyron.com/else/streamgraph/.
36+
37+
2838
*colors* : A list or tuple of colors. These will be cycled through and
2939
used to colour the stacked areas.
3040
All other keyword arguments are passed to
@@ -44,17 +54,58 @@ def stackplot(axes, x, *args, **kwargs):
4454
if colors is not None:
4555
axes.set_color_cycle(colors)
4656

57+
baseline = kwargs.pop('baseline', 'zero')
4758
# Assume data passed has not been 'stacked', so stack it here.
4859
y_stack = np.cumsum(y, axis=0)
4960

5061
r = []
62+
if baseline == 'zero':
63+
first_line = 0.
64+
65+
elif baseline == 'sym':
66+
first_line = -np.sum(y, 0) * 0.5
67+
y_stack += first_line[None, :]
68+
69+
elif baseline == 'wiggle':
70+
m = y.shape[0]
71+
first_line = (y * (m - 0.5 - np.arange(0, m)[:, None])).sum(0)
72+
first_line /= -m
73+
y_stack += first_line
74+
75+
elif baseline == 'weighted_wiggle':
76+
#TODO: Vectorize this stuff.
77+
m, n = y.shape
78+
center = np.zeros(n)
79+
total = np.sum(y, 0)
80+
for i in range(n):
81+
if i > 0:
82+
center[i] = center[i - 1]
83+
for j in range(m):
84+
if i == 0:
85+
increase = y[j, i]
86+
moveUp = 0.5
87+
else:
88+
belowSize = 0.5 * y[j, i]
89+
for k in range(j + 1, m):
90+
belowSize += y[k, i]
91+
increase = y[j, i] - y[j, i - 1]
92+
moveUp = belowSize / total[i]
93+
center[i] += (moveUp - 0.5) * increase
94+
first_line = center - 0.5 * total
95+
y_stack += first_line
96+
else:
97+
errstr = "Baseline method %s not recognised. " % baseline
98+
errstr += "Expected 'zero', 'sym', 'wiggle' or 'weighted_wiggle'"
99+
raise ValueError(errstr)
51100

52101
# Color between x = 0 and the first array.
53-
r.append(axes.fill_between(x, 0, y_stack[0, :],
54-
facecolor=axes._get_lines.color_cycle.next(), **kwargs))
102+
r.append(axes.fill_between(x, first_line, y_stack[0,:],
103+
facecolor=axes._get_lines.color_cycle.next(),
104+
**kwargs))
55105

56106
# Color between array i-1 and array i
57-
for i in xrange(len(y) - 1):
58-
r.append(axes.fill_between(x, y_stack[i, :], y_stack[i + 1, :],
59-
facecolor=axes._get_lines.color_cycle.next(), **kwargs))
107+
for i in xrange(len(y)-1):
108+
r.append(axes.fill_between(x, y_stack[i,: ], y_stack[i + 1, :],
109+
facecolor=axes._get_lines.color_cycle.next(),
110+
**kwargs))
60111
return r

0 commit comments

Comments
 (0)