отображать значение столбцов, когда столбцы сгруппированы - PullRequest
1 голос
/ 02 августа 2020

Хотя есть много ответов о stackoverflow для добавления значений в отдельные столбцы, я не смог найти подходящий способ добавления точных значений в мои сгруппированные столбцы. Вот как я создаю свою гистограмму:

labels = ['<20','20-29', '30-39','40-49','50-59','60-69','70-79','80+']
maleAges = (malesUnder20, males20To30, males30To40)
femaleAges = (femalesUnder20, females20To30,males30To40)

# bars = []

def subcategorybar(X, vals, width=0.8):
    n = len(vals)
    _X = np.arange(len(X))
    for i in range(n):
        bar = plt.bar(_X - width/2. + i/float(n)*width, vals[i], 
                width=width/float(n), align="edge")
        bars.append(bar)
    plt.xticks(_X, X)
subcategorybar(labels, [maleAges, femaleAges])

Я пробовал использовать эту функцию

def autolabel(rects):
    for rect in rects:
        height = rect.get_height()
        ax.text(rect.get_x() + rect.get_width()/2., 1.05*height,
                '%d' % int(height),
                ha='center', va='bottom')      

и передал bars из подкатегории fun c, но это дает мне ошибка, которая

AttributeError: 'BarContainer' object has no attribute 'get_height'

Альтернативным способом было бы использовать plt.text и plt.annotate, но в данном конкретном случае я не смог определить правильные параметры для обоих.

Изменить:

Второй способ, которым я нарисовал свою диаграмму, был таким:

N = 3
labels = ['<20','20-29', '30-39','40-49']
maleAges = (malesUnder20, males20To30, males30To40)
femaleAges = (femalesUnder20, females20To30,males30To40)
ind = np.arange(N) 
width = 0.35  

plt.figure(figsize=(10,5))
plt.bar(ind, maleAges , width, label='Male')
plt.bar(ind + width, femaleAges, width, label='Female')

plt.xticks(ind + width / 2,  ('<20','20-29', '30-39'))

plt.legend(loc='best')
plt.show()

Я также пробовал использовать здесь plt.annotations, но не работал.

A может оказаться полезным решение с помощью любого из двух вышеперечисленных методов. Примечание. Я ищу способы отредактировать существующие функции.

1 Ответ

1 голос
/ 03 августа 2020

Вы можете сделать это прямо из патчей axes:

for p in axes.patches:
    axes.annotate(s=np.round(p.get_height(), decimals=2),
                xy=(p.get_x()+p.get_width()/2., p.get_height()),
                ha='center',
                va='center',
                xytext=(0, 10),
                textcoords='offset points')

Эффект в вашем примере:

import numpy as np
import matplotlib.pyplot as plt

N = 3
labels = ['<20','20-29', '30-39','40-49']
maleAges = (1, 2, 3)
femaleAges = (1, 3, 4)
ind = np.arange(N) 
width = 0.35  

figure, axes = plt.subplots()

plt.bar(ind, maleAges , width, label='Male')
plt.bar(ind + width, femaleAges, width, label='Female')

plt.xticks(ind + width / 2,  ('<20','20-29', '30-39'))

for p in axes.patches:
    axes.annotate(s=np.round(p.get_height(), decimals=2),
                xy=(p.get_x()+p.get_width()/2., p.get_height()),
                ha='center',
                va='center',
                xytext=(0, 10),
                textcoords='offset points')

plt.legend(loc='best')
plt.show()

введите описание изображения здесь

...