Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save rileypeterson/8036397aed39492e9dca7a60701c6cbc to your computer and use it in GitHub Desktop.
Save rileypeterson/8036397aed39492e9dca7a60701c6cbc to your computer and use it in GitHub Desktop.
matplotlib.axes.Axes.bar does not support stacking out of the box. pandas.DataFrame.plot.bar does support stacking, but not ordered stacking. Here is an implementation of ordered stacking.
import matplotlib.pyplot as plt
import pandas as pd
import numpy as np
a = pd.DataFrame({'a':[0.25, 0.5, 0.15, 0], 'b':[0.15, 0.25, 0.35, 0.15],
'c':[0.50, 0.15, 0.5, 0.35], 'd':[0.35, 0.35, 0.25, 0.5],})
fig, ax = plt.subplots()
x = a.index
indexes = np.argsort(a.values).T
heights = np.sort(a.values).T
order = -1
bottoms = heights[::order].cumsum(axis=0)
bottoms = np.insert(bottoms, 0, np.zeros(len(bottoms[0])), axis=0)
mpp_colors = dict(zip(a.columns, plt.rcParams['axes.prop_cycle'].by_key()['color']))
for btms, (idxs, vals) in enumerate(list(zip(indexes, heights))[::order]):
mps = np.take(np.array(a.columns), idxs)
ax.bar(x, height=vals, bottom=bottoms[btms], color=[mpp_colors[m] for m in mps])
ax.set_ylim(bottom=0, top=2)
plt.legend((np.take(np.array(a.columns), np.argsort(a.values)[0]))[::order], loc='upper right')
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment