@@ -25,6 +25,16 @@ def stackplot(axes, x, *args, **kwargs):
2525
2626 Keyword arguments:
2727
28+ *baseline* : ['zero', 'sym', 'wiggle', 'weighted_wiggle']
29+ Method used to calculate the 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 at 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,51 @@ 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.
48- y_stack = np .cumsum (y , axis = 0 )
59+ 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+ 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+ stack += first_line
74+
75+ elif baseline == 'weighted_wiggle' :
76+ m , n = y .shape
77+ center = np .zeros (n )
78+ total = np .sum (y , 0 )
79+ increase = np .hstack ((y [:, 0 :1 ], np .diff (y )))
80+ below_size = total - stack
81+ below_size += 0.5 * y
82+ move_up = below_size / total
83+ move_up [:, 0 ] = 0.5
84+ center = (move_up - 0.5 ) * increase
85+ center = np .cumsum (center .sum (0 ))
86+ first_line = center - 0.5 * total
87+ stack += first_line
88+ else :
89+ errstr = "Baseline method %s not recognised. " % baseline
90+ errstr += "Expected 'zero', 'sym', 'wiggle' or 'weighted_wiggle'"
91+ raise ValueError (errstr )
5192
5293 # 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 ))
94+ r .append (axes .fill_between (x , first_line , stack [0 , :],
95+ facecolor = axes ._get_lines .color_cycle .next (),
96+ ** kwargs ))
5597
5698 # Color between array i-1 and array i
5799 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 ))
100+ color = axes ._get_lines .color_cycle .next ()
101+ r .append (axes .fill_between (x , stack [i , :], stack [i + 1 , :],
102+ facecolor = color ,
103+ ** kwargs ))
60104 return r
0 commit comments