9

I am trying to make a multiple stacked bar plot with pandas but I'm running into issues. Here is a sample code:

import pandas as pd

df = pd.DataFrame({'a':[10, 20], 'b': [15, 25], 'c': [35, 40], 'd':[45, 50]}, index=['john', 'bob'])

ax = df[['a', 'c']].plot.bar(width=0.1, stacked=True)
ax=df[['b', 'd']].plot.bar(width=0.1, stacked=True, ax=ax)
df[['a', 'd']].plot.bar(width=0.1, stacked=True, ax=ax)

Which produces the following plot:

enter image description here

As you can see, the bars within each cluster are plotted on top of each other, which is not what I want to achieve. I want the bars within the same cluster to be plotted next to each other. I tried to play with the "position" argument but without much success.

Any idea on how to achieve this?

Moncef M.
  • 1,223
  • 2
  • 14
  • 15

1 Answers1

19

You could do it by shifting the position parameter of a bar-plot so that they are adjacent to each other as shown:

matplotlib.style.use('ggplot')

fig, ax = plt.subplots()
df[['a', 'c']].plot.bar(stacked=True, width=0.1, position=1.5, colormap="bwr", ax=ax, alpha=0.7)
df[['b', 'd']].plot.bar(stacked=True, width=0.1, position=-0.5, colormap="RdGy", ax=ax, alpha=0.7)
df[['a', 'd']].plot.bar(stacked=True, width=0.1, position=0.5, colormap="BrBG", ax=ax, alpha=0.7)
plt.legend(loc="upper center")
plt.show()

enter image description here

Nickil Maveli
  • 29,155
  • 8
  • 82
  • 85
  • I'm confused. The doc says that the "position" argument goes from 0 to 1, and yet you are using values below 0 and above 1. How does that work? – Moncef M. Aug 18 '16 at 09:37
  • 2
    Nice observation! As you would know that pandas inherits the keyword arguments that are present in a `matplotlib` object, you could leverage it to tweak various settings. One such case is using the `align` parameter of a `matplotlib - bar` plot to alter the `position` parameter of a `pandas - bar` plot. You could refer the [`source code`](https://github.com/pydata/pandas/blob/master/pandas/tools/plotting.py#L1904) too which uses the [`align`](http://matplotlib.org/api/pyplot_api.html#matplotlib.pyplot.bar) option and it allows both *pos/neg* floating point numbers to be set. – Nickil Maveli Aug 18 '16 at 10:22
  • 1
    Ok, so if I understand correctly, it works because under the hood, the pandas bar is just a regular matplotlib bar, whose "align" property does take values below 0 and above 1. Thanks for the explanation! – Moncef M. Aug 18 '16 at 11:45
  • how can I decrease space between the two groups? – Khalil Al Hooti Jan 03 '20 at 19:00