@@ -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