Home > database >  How to add multiple data labels in a bar chart in matplotlib
How to add multiple data labels in a bar chart in matplotlib

Time:09-22

I have two grouped bar charts of value changes between cases for two systems among 3 groups as below. Here I was able to add data labels to the bars using the code below (figure produced attached)Figure produced from code

What I want to do is on top (or bottom for the negative change in value cases), add an extra data label that captures the % of the value changes as shown in the second figure with the 33% in red (I edited it in by hands). How do I achieve that from this code? Thank you in advance.Figure I want to achieve

import matplotlib.pyplot as plt
import numpy as np

value_case0_system1 = np.array([30, 20, 40])
value_case1_system1 = np.array([20, 25, 50])
value_case2_system1 = np.array([10, 35, 45])

value_case1_system2 = np.array([60, 50, 40])
value_case2_system2 = np.array([50, 40, 55])

change_case0_to_case1_system1 = np.subtract(value_case1_system1,value_case0_system1)
change_case1_to_case2_system1 = np.subtract(value_case2_system1,value_case1_system1)
change_case1_to_case2_system2 = np.subtract(value_case2_system2,value_case1_system2)

fig, (ax0, ax1) = plt.subplots(nrows=1, ncols=2, sharey=True, figsize=(18,10))
labels = ['Group 1', 'Group 2', 'Group 3']
x = np.arange(len(labels))
ax0.set_ylabel('Change in Values', va='center', rotation='vertical',
         fontsize=17, fontweight='bold')
width = 0.28
ax0.set_title('System 1', fontsize=17, fontweight='bold')
ax0.axhline(y=0, color='black', ls=':', lw=2)
ax0.set_xticks(x)
ax0.set_xticklabels(labels,fontsize=15)
rects1 = ax0.bar(x-width/2, change_case0_to_case1_system1, width, label='Case 0 to Case 1',
        color='#292929', edgecolor='black', linewidth=1)
rects2 = ax0.bar(x width/2, change_case1_to_case2_system1, width, label='Case 1 to Case 2',
        color='#7f6d5f', edgecolor='black', linewidth=1)
ax0.bar_label(rects1, padding=3, fontsize=11)
ax0.bar_label(rects2, padding=3, fontsize=11)
leg = ax0.legend(loc="upper left", bbox_to_anchor=[0, 1],
                 ncol=1, fancybox=True)
ax0.legend(fontsize=15)

ax1.set_title('System 2', fontsize=17, fontweight='bold')
ax1.axhline(y=0, color='black', ls=':', lw=2)
ax1.set_xticks(x)
ax1.set_xticklabels(labels,fontsize=15)

rects3 = ax1.bar(x, change_case1_to_case2_system2, width, label='Case 1 to Case 2',
        color='#7f6d5f', edgecolor='black', linewidth=1)
ax1.legend(shadow=True, fancybox=True)
ax1.bar_label(rects3, padding=3, fontsize=11)
leg = ax1.legend(loc="upper left", bbox_to_anchor=[0, 1],
                 ncol=1, fancybox=True)
ax1.legend(fontsize=15)
plt.tight_layout()
plt.show()

CodePudding user response:

  • The code for the extra plot formatting has been left out, because it's not relevant for the answer. It can be added back, as per your requirements.
  • Each enter image description here

  • Related