As of Matplotlib 3.4.0 this can be accomplished with bar_labels
and zipping containers with the labels:
# Save axes returned from DataFrame plot
ax = df.plot.barh()
# Iterate over containers and all_labels together
for container, labels in zip(ax.containers, all_labels):
ax.bar_label(container, labels=labels, label_type='center')
- Labels will align with indexes of the DataFrame:
- The first list in
all_labels
will align with column 0 (Unmarried woman
) and continue across the columns
- Index 0 in each sub-list (
labels
) will align with index 0 in the DataFrame which is Africa
and continue down the rows.
All Together:
import matplotlib.pyplot as plt
import pandas as pd
plt.style.use('seaborn-notebook')
unmarried_labels = ['30–55', '14–50', '16-59', '16-24', '13-26']
married_labels = ['25–50', '29–59', '34–89', '11–18', '33–55']
all_labels = [unmarried_labels, married_labels]
df = pd.DataFrame({'Unmarried woman': [36, 23, 28, 20, 16],
'Married woman': [26, 38, 49, 14, 38]},
columns=['Unmarried woman', 'Married woman'],
index=['Africa', 'Asia', 'Latin America', 'Northern America',
'Europe'])
# Save axes returned from DataFrame plot
ax = df.plot.barh()
# Iterate over containers and all_labels together
for container, labels in zip(ax.containers, all_labels):
ax.bar_label(container, labels=labels, label_type='center')
plt.title(
'Abortion rate per 1000 women aged 15–44 y. by marital status (2010–2014)',
fontweight='bold',
fontsize=11
)
plt.tight_layout()
plt.show()
