1

I made a stacked barplot in matplotlib and want to print the total of each bar at the top,

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt

df = pd.DataFrame()
df['year'] = ['2012','2013','2014']
df['test 1'] = [4,17,5]
df['test 2'] = [1,4,1]
df['test 2a'] = [1,1,2]
df['test 3'] = [2,1,8]
df['test 4'] = [2,1,5]
df['test 4a'] = [2,1,7]
df = df.set_index('year')
df['total'] = df.sum(axis=1)

fig, ax = plt.subplots(1,1)
df.drop(columns=['total']).plot(kind='bar', stacked=True, ax=ax)

# iterate through each group of container (bar) objects
for c in ax.containers:
    # annotate the container group
    ax.bar_label(c, label_type='center')

##for p in ax.patches:
##    width, height = p.get_width(), p.get_height()
##    x, y = p.get_xy() 
##    ax.text(x+width/2, 
##            y+height/2, 
##            '{:.0f}'.format(height), 
##            horizontalalignment='center', 
##            verticalalignment='center')

I tried using the answers in other posts, eg here and here but they print the values for every section. I'm looking for a graph like below with black text showing 12, 15, 18 values for each stacked bar. Ideally I could print the numbers in df['total'] above each stack, but I'm not sure how to do this.

enter image description here

Medulla Oblongata
  • 3,771
  • 8
  • 36
  • 75

1 Answers1

0

You can simply add a label without label_type='center' for the last conatiner:

for c in ax.containers:
    # annotates each group
    ax.bar_label(c, label_type='center')

# annotates total
ax.bar_label(ax.containers[-1], color='red')

Output: enter image description here

Tranbi
  • 11,407
  • 6
  • 16
  • 33