How can I create stacked line graph with matplotlib?

Newer versions of matplotlib contain the function plt.stackplot, which allow for several different "out-of-the-box" stacked area plots:

import numpy as np
import pylab as plt

X = np.arange(0, 10, 1) 
Y = X + 5 * np.random.random((5, X.size))

baseline = ["zero", "sym", "wiggle", "weighted_wiggle"]
for n, v in enumerate(baseline):
    plt.subplot(2 ,2, n + 1)
    plt.stackplot(X, *Y, baseline=v)
    plt.title(v)
    plt.axis('tight')
plt.show()

Stack Plot using plt.stackplot.


I believe Area Plot is a common term for this type of plot, and in the specific instance recited in the OP, Stacked Area Plot.

Matplotlib does not have an "out-of-the-box" function that combines both the data processing and drawing/rendering steps to create a this type of plot, but it's easy to roll your own from components supplied by Matplotlib and NumPy.

The code below first stacks the data, then draws the plot.

import numpy as NP
from matplotlib import pyplot as PLT

# just create some random data
fnx = lambda : NP.random.randint(3, 10, 10)
y = NP.row_stack((fnx(), fnx(), fnx()))   
# this call to 'cumsum' (cumulative sum), passing in your y data, 
# is necessary to avoid having to manually order the datasets
x = NP.arange(10) 
y_stack = NP.cumsum(y, axis=0)   # a 3x10 array

fig = PLT.figure()
ax1 = fig.add_subplot(111)

ax1.fill_between(x, 0, y_stack[0,:], facecolor="#CC6666", alpha=.7)
ax1.fill_between(x, y_stack[0,:], y_stack[1,:], facecolor="#1DACD6", alpha=.7)
ax1.fill_between(x, y_stack[1,:], y_stack[2,:], facecolor="#6E5160")

PLT.show()

example of stacked area plot


If you have a dataframe, it's quite easy:

df = pd.DataFrame(np.random.rand(10, 4), columns=['a', 'b', 'c', 'd'])
df.plot.area();

enter image description here

From: pandas documentation


A slightly less hackish way would be to use a line graph in the first place and matplotlib.pyplot.fill_between. To emulate the stacking you have to shift the points up yourself.

x = np.arange(0,4)
y1 = np.array([1,2,4,3])
y2 = np.array([5,2,1,3])
# y2 should go on top, so shift them up
y2s = y1+y2

plot(x,y1)
plot(x,y2s)
fill_between(x,y1,0,color='blue')
fill_between(x,y1,y2s,color='red')