Skip to content

Commit 5675ffa

Browse files
committed
Merged matplotlib#819: dmcdougall's stackplot
1 parent 068cad2 commit 5675ffa

File tree

10 files changed

+778
-1
lines changed

10 files changed

+778
-1
lines changed

CHANGELOG

+3
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,9 @@
4141
the linear portion relative to the logarithmic portion to be
4242
adjusted. - MGD
4343

44+
2012-04-14 Added new plot style: stackplot. This new feature supports stacked
45+
area plots. - Damon McDougall
46+
4447
2012-04-06 When path clipping changes a LINETO to a MOVETO, it also
4548
changes any CLOSEPOLY command to a LINETO to the initial
4649
point. This fixes a problem with pdf and svg where the

boilerplate.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,6 @@ def %(func)s(%(argspec)s):
6969
return %(ret)s
7070
"""
7171

72-
7372
# Used for colormap functions
7473
CMAP_TEMPLATE = AUTOGEN_MSG + """
7574
def {name}():
@@ -131,6 +130,7 @@ def boilerplate_gen():
131130
'semilogy',
132131
'specgram',
133132
#'spy',
133+
'stackplot',
134134
'stem',
135135
'step',
136136
'streamplot',
+18
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
import numpy as np
2+
from matplotlib import pyplot as plt
3+
4+
fnx = lambda : np.random.randint(5, 50, 10)
5+
y = np.row_stack((fnx(), fnx(), fnx()))
6+
x = np.arange(10)
7+
8+
y1, y2, y3 = fnx(), fnx(), fnx()
9+
10+
fig = plt.figure()
11+
ax = fig.add_subplot(111)
12+
ax.stackplot(x, y)
13+
plt.show()
14+
15+
fig = plt.figure()
16+
ax = fig.add_subplot(111)
17+
ax.stackplot(x, y1, y2, y3)
18+
plt.show()

lib/matplotlib/axes.py

+5
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
import matplotlib.spines as mspines
3030
import matplotlib.quiver as mquiver
3131
import matplotlib.scale as mscale
32+
import matplotlib.stackplot as mstack
3233
import matplotlib.streamplot as mstream
3334
import matplotlib.table as mtable
3435
import matplotlib.text as mtext
@@ -6410,6 +6411,10 @@ def quiver(self, *args, **kw):
64106411
return q
64116412
quiver.__doc__ = mquiver.Quiver.quiver_doc
64126413

6414+
def stackplot(self, x, *args, **kwargs):
6415+
return mstack.stackplot(self, x, *args, **kwargs)
6416+
stackplot.__doc__ = mstack.stackplot.__doc__
6417+
64136418
def streamplot(self, x, y, u, v, density=1, linewidth=None, color=None,
64146419
cmap=None, norm=None, arrowsize=1, arrowstyle='-|>',
64156420
minlength=0.1):

lib/matplotlib/pyplot.py

+19
Original file line numberDiff line numberDiff line change
@@ -1636,6 +1636,7 @@ def plotting():
16361636
until they have been closed; in interactive mode,
16371637
show generally has no effect.
16381638
specgram a spectrogram plot
1639+
stackplot make a stacked plot
16391640
stem make a stem plot
16401641
subplot make a subplot (numrows, numcols, axesnum)
16411642
table add a table to the axes
@@ -2978,6 +2979,24 @@ def specgram(x, NFFT=256, Fs=2, Fc=0, detrend=mlab.detrend_none,
29782979
sci(ret[-1])
29792980
return ret
29802981

2982+
# This function was autogenerated by boilerplate.py. Do not edit as
2983+
# changes will be lost
2984+
@autogen_docstring(Axes.stackplot)
2985+
def stackplot(x, *args, **kwargs):
2986+
ax = gca()
2987+
# allow callers to override the hold state by passing hold=True|False
2988+
washold = ax.ishold()
2989+
hold = kwargs.pop('hold', None)
2990+
if hold is not None:
2991+
ax.hold(hold)
2992+
try:
2993+
ret = ax.stackplot(x, *args, **kwargs)
2994+
draw_if_interactive()
2995+
finally:
2996+
ax.hold(washold)
2997+
2998+
return ret
2999+
29813000
# This function was autogenerated by boilerplate.py. Do not edit as
29823001
# changes will be lost
29833002
@autogen_docstring(Axes.stem)

lib/matplotlib/stackplot.py

+60
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
"""
2+
Stacked area plot for 1D arrays inspired by Douglas Y'barbo's stackoverflow
3+
answer:
4+
http://stackoverflow.com/questions/2225995/how-can-i-create-stacked-line-graph-with-matplotlib
5+
6+
(http://stackoverflow.com/users/66549/doug)
7+
8+
"""
9+
import numpy as np
10+
import matplotlib
11+
12+
__all__ = ['stackplot']
13+
14+
15+
def stackplot(axes, x, *args, **kwargs):
16+
"""Draws a stacked area plot.
17+
18+
Parameters
19+
----------
20+
*x* : 1d array of dimension N
21+
*y* : 2d array of dimension MxN, OR any number 1d arrays each of dimension
22+
1xN. The data is assumed to be unstacked. Each of the following
23+
calls is legal:
24+
25+
stackplot(x, y) # where y is MxN
26+
staclplot(x, y1, y2, y3, y4) # where y1, y2, y3, y4, are all 1xNm
27+
28+
Keyword arguments:
29+
*colors* : A list or tuple of colors. These will be cycled through and
30+
used to colour the stacked areas.
31+
All other keyword arguments are passed to
32+
:func:`~matplotlib.Axes.fill_between`
33+
34+
Returns
35+
-------
36+
*r* : A list of :class:`~matplotlib.collections.PolyCollection`, one for
37+
each element in the stacked area plot.
38+
"""
39+
40+
if len(args) == 1:
41+
y = np.atleast_2d(*args)
42+
elif len(args) > 1:
43+
y = np.row_stack(args)
44+
45+
colors = kwargs.pop('colors', None)
46+
if colors is not None:
47+
axes.set_color_cycle(colors)
48+
49+
# Assume data passed has not been 'stacked', so stack it here.
50+
y_stack = np.cumsum(y, axis=0)
51+
52+
r = []
53+
54+
# Color between x = 0 and the first array.
55+
r.append(axes.fill_between(x, 0, y_stack[0,:], facecolor=axes._get_lines.color_cycle.next(), **kwargs))
56+
57+
# Color between array i-1 and array i
58+
for i in xrange(len(y)-1):
59+
r.append(axes.fill_between(x, y_stack[i,:], y_stack[i+1,:], facecolor=axes._get_lines.color_cycle.next(), **kwargs))
60+
return r
Binary file not shown.
Loading

0 commit comments

Comments
 (0)