Horizontal stacked bar chart in Matplotlib


Question

I'm trying to create a horizontal stacked bar chart using matplotlib but I can't see how to make the bars actually stack rather than all start on the y-axis.

Here's my testing code.

fig = plt.figure()
ax = fig.add_subplot(1,1,1)
plot_chart(df, fig, ax)
ind = arange(df.shape[0])      
ax.barh(ind, df['EndUse_91_1.0'], color='#FFFF00')
ax.barh(ind, df['EndUse_91_nan'], color='#FFFF00')
ax.barh(ind, df['EndUse_80_1.0'], color='#0070C0')
ax.barh(ind, df['EndUse_80_nan'], color='#0070C0')
plt.show()

Edited to use left kwarg after seeing tcaswell's comment.

fig = plt.figure()
ax = fig.add_subplot(1,1,1)
plot_chart(df, fig, ax)
ind = arange(df.shape[0])      
ax.barh(ind, df['EndUse_91_1.0'], color='#FFFF00')
lefts = df['EndUse_91_1.0']
ax.barh(ind, df['EndUse_91_nan'], color='#FFFF00', left=lefts)
lefts = lefts + df['EndUse_91_1.0']
ax.barh(ind, df['EndUse_80_1.0'], color='#0070C0', left=lefts)
lefts = lefts + df['EndUse_91_1.0']
ax.barh(ind, df['EndUse_80_nan'], color='#0070C0', left=lefts)
plt.show()

This seems to be the right approach, but it fails if there is no data for a particular bar as it's trying to add nan to a value which then returns nan.

1
9
5/20/2013 4:43:15 PM

Accepted Answer

Since you are using pandas, it's worth mentioning that you can do stacked bar plots natively:

df2.plot(kind='bar', stacked=True)

See the visualisation section of the docs.

7
5/20/2013 5:00:19 PM

Here's a solution, although I'm sure there must be a better way of doing it. The series.fillna(0) part replaces any nan with 0.

fig = plt.figure()
ax = fig.add_subplot(1,1,1)
plot_chart(df, fig, ax)
ind = arange(df.shape[0])      
ax.barh(ind, df['EndUse_91_1.0'], color='#FFFF00')
lefts = df['EndUse_91_1.0'].fillna(0)
ax.barh(ind, df['EndUse_91_nan'], color='#FFFF00', left=lefts)
lefts = lefts + df['EndUse_91_1.0'].fillna(0)
ax.barh(ind, df['EndUse_80_1.0'], color='#0070C0', left=lefts)
lefts = lefts + df['EndUse_91_1.0'].fillna(0)
ax.barh(ind, df['EndUse_80_nan'], color='#0070C0', left=lefts)
plt.show()

Licensed under: CC-BY-SA with attribution
Not affiliated with: Stack Overflow
Icon