Using the following code, I've added value labels to the horizontal stacked bar plot in Matplotlib:
import pandas
import matplotlib.pyplot as plt
import numpy as np
%matplotlib inline
def sumzip(*items):
return [sum(values) for values in zip(*items)]
fig, ax = plt.subplots(figsize=(10,6))
N = 5
values1 = [130, 120, 170, 164, 155]
values2 = [120, 185, 162, 150, 153]
values3 = [100, 170, 160, 145, 150]
ind = np.arange(N) + .15
width = 0.3
rects1 = plt.barh(ind, values1, width, color='blue')
rects2 = plt.barh(ind, values2, width, left = sumzip(values1), color='green')
rects3 = plt.barh(ind, values3, width, left = sumzip(values1, values2), color='red')
extra_space = 0.15
ax.set_yticks(ind+width-extra_space)
ax.set_yticklabels( ('Label1', 'Label2', 'Label3', 'Label4', 'Label5') )
ax.yaxis.set_tick_params(length=0,labelbottom=True)
for i, v in enumerate(values1):
plt.text(v * 0.45, i + .145, str(v), color='white', fontweight='bold', fontsize=10,
ha='center', va='center')
for i, v in enumerate(values2):
plt.text(v * 1.45, i + .145, str(v), color='white', fontweight='bold', fontsize=10,
ha='center', va='center')
for i, v in enumerate(values3):
plt.text(v * 2.45, i + .145, str(v), color='white', fontweight='bold', fontsize=10,
ha='center', va='center')
ax.spines['right'].set_visible(False)
ax.spines['top'].set_visible(False)
plt.show()
And the code gives me the following result:

As you can see, the labels in green and red sections are not aligned properly. What to I need to do to correct this issue?
The factors 1.45 and 2.45 will give the desired result only when the numbers in values1, values2, values3 are all equal.
You need to do the following:
For the second bar, x = first bar value + 0.45 * second bar value
For the third bar, x = first bar value + second bar value + 0.45 * third bar value
Following is how you can do it.
# Use values1[i] + v * 0.45 as the x-coordinate
for i, v in enumerate(values2):
plt.text(values1[i] + v * 0.45, i + .145, str(v), color='white', fontweight='bold', fontsize=10,
ha='center', va='center')
# Use values1[i] + values2[i] + v * 0.45 as the x-coordinate
for i, v in enumerate(values3):
plt.text(values1[i] + values2[i] + v * 0.45, i + .145, str(v), color='white', fontweight='bold', fontsize=10,
ha='center', va='center')

Simply add the value from each of the previous lists with the corresponding index, like this:
for i, v in enumerate(values1):
plt.text(v * 0.45, i + .145, str(v), color='white', fontweight='bold', fontsize=10,
ha='center', va='center')
for i, v in enumerate(values2):
plt.text(v * 0.45 + values1[i], i + .145, str(v), color='white', fontweight='bold', fontsize=10,
ha='center', va='center')
for i, v in enumerate(values2):
plt.text(v * 0.45 + values1[i] + values2[i], i + .145, str(v), color='white', fontweight='bold', fontsize=10,
ha='center', va='center')
Result:

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With