rastawolf
rastawolf

Reputation: 338

How to Create Partially Stacked Bar Plot

I want to make a partially stacked bar plot of n elements where n - 1 elements are stacked, and the remaining element is another bar adjacent to the stacked bars of equal width. The adjacent bar element is plotted on a secondary y-axis and is typically a percentage, plotted between 0 and 1.

The solution that I am currently using is able to represent the data fine, but I'm curious to know how I could achieve the desired result of an equal width single bar next to a stacked bar.

import pandas as pd
import numpy as np
from matplotlib import pyplot as plt
import matplotlib.patches as mpatches

mylabels=list('BCD')

df = pd.DataFrame(np.random.randint(1,11,size=(5,4)), columns=list('ABCD'))
df['A'] = list('abcde')
df['D'] = np.random.rand(5,1)

ax = df.loc[:,~df.columns.isin(['D'])].plot(kind='bar', stacked=True, x='A', figsize=(15,7))
ax2 = ax.twinx()
ax2.bar(df.A,df.D, color='g', width=.1)
ax2.set_ylim(0,1)
handles, labels = ax.get_legend_handles_labels()
green_patch = mpatches.Patch(color='g')
handles.append(green_patch)
ax.legend(handles=handles, labels=mylabels)
ax.set_xlabel('')

Example

Upvotes: 1

Views: 400

Answers (1)

Quang Hoang
Quang Hoang

Reputation: 150725

Let's try passing align='edge' and width to control the relative position of the bars:

ax = df.drop('D', axis=1).plot.bar(x='A', stacked=True, align='edge', width=-0.4)
ax1=ax.twinx()


df.plot.bar(x='A',y='D', width=0.4, align='edge', ax=ax1, color='C2')

# manually set the limit so the left most bar isn't cropped
ax.set_xlim(-0.5)


# handle the legends
handles, labels = ax.get_legend_handles_labels()
h, l = ax1.get_legend_handles_labels()
ax.legend(handles=handles + h, labels=mylabels+l)
ax1.legend().remove()

Output:

enter image description here

Upvotes: 3

Related Questions