Stacked bar chart in Seaborn

Question:

I have the following data:

countries2012 = [
    'Bolivia',
    'Brazil',
    'Sri Lanka',
    'Dominican Republic',
    'Indonesia',
    'Kenya',
    'Honduras',
    'Mozambique',
    'Peru',
    'Philipines',
    'India',
    'Vietnam',
    'Thailand',
    'USA',
    'World'
]

percentage2012 = [ 
    0.042780099,
    0.16599952,
    0.012373058,
    0.019171717,
    0.011868674,
    0.019239173,
    0.00000332,
    0.014455196,
    0.016006654,
    0.132970981,
    0.077940824,
    0.411752517,
    0.017986798,
    0.017361808,
    0.058076027
]

countries2013 = [
    'Bolivia',
    'Brazil',
    'Sri Lanka',
    'Dominican Republic', 
    'Indonesia', 
    'Honduras',
    'Mozambique', 
    'Peru', 
    'Philippines', 
    'India', 
    'Vietnam', 
    'Thailand', 
    'USA',
    'World'  
]

percentage2013 = [
    0.02736294,
    0.117160272, 
    0.015815952 ,
    0.018831589,
    0.020409103 ,
    0.00000000285,
    0.018876854,
    0.018998639,
    0.117221146,
    0.067991687,
    0.496110972,
    0.019309486,
    0.026880553,
    0.03503080414999993
]

I want to make a stacked bar plot so that there’s a stacked bar for 2012 and another for 2013.

How can I go about this since the countries in 2012 and 2013 are different?

Asked By: Corp. and Ltd.

||

Answers:

IIUC, you can create a Pandas dataframe and use its plot function:

import pandas as pd
df = pd.concat([pd.DataFrame({2012:percentage2012}, index=countries2012),
                pd.DataFrame({2013:percentage2013}, index=countries2013)],
               axis=1, sort=False)

df.T.plot.bar(stacked=True, figsize=(12,6))

Output:

enter image description here

Answered By: Quang Hoang

Since this question asked for a stacked bar chart in Seaborn and the accepted answer uses pandas, I thought I’d give an alternative approach that actually uses Seaborn.

Seaborn gives an example of a stacked bar but it’s a bit hacky, plotting the total and then overlaying bars on top of it. Instead, you can actually use the histogram plot and weights argument.

import pandas as pd
import seaborn as sns

# Put data in long format in a dataframe.
df = pd.DataFrame({
    'country': countries2012 + countries2013,
    'year': ['2012'] * len(countries2012) + ['2013'] * len(countries2013),
    'percentage': percentage2012 + percentage2013
})

# One liner to create a stacked bar chart.
ax = sns.histplot(df, x='year', hue='country', weights='percentage',
             multiple='stack', palette='tab20c', shrink=0.8)
ax.set_ylabel('percentage')
# Fix the legend so it's not on top of the bars.
legend = ax.get_legend()
legend.set_bbox_to_anchor((1, 1))

seaborn stacked bar chart

Answered By: getup8