webentwicklung-frage-antwort-db.com.de

Wie kann der Wert des Balkens mit pyplot.barh () auf jedem Balken angezeigt werden?

Ich habe ein Balkendiagramm erstellt. Wie kann ich den Wert des Balkens in jedem Balken anzeigen?

Aktuelle Handlung:

enter image description here

Was ich versuche zu bekommen:

enter image description here

Mein Code:

import os
import numpy as np
import matplotlib.pyplot as plt

x = [u'INFO', u'CUISINE', u'TYPE_OF_PLACE', u'DRINK', u'PLACE', u'MEAL_TIME', u'DISH', u'NEIGHBOURHOOD']
y = [160, 167, 137, 18, 120, 36, 155, 130]

fig, ax = plt.subplots()    
width = 0.75 # the width of the bars 
ind = np.arange(len(y))  # the x locations for the groups
ax.barh(ind, y, width, color="blue")
ax.set_yticks(ind+width/2)
ax.set_yticklabels(x, minor=False)
plt.title('title')
plt.xlabel('x')
plt.ylabel('y')      
#plt.show()
plt.savefig(os.path.join('test.png'), dpi=300, format='png', bbox_inches='tight') # use format='svg' or 'pdf' for vectorial pictures
46

Hinzufügen: 

for i, v in enumerate(y):
    ax.text(v + 3, i + .25, str(v), color='blue', fontweight='bold')

ergebnis:

enter image description here

Die y-Werte v sind sowohl die x-Position als auch die Zeichenfolgewerte für ax.text. In günstiger Weise hat das Balkendiagramm eine Metrik von 1 für jeden Takt, so dass die Aufzählung i die y-Position ist. 

93
cphlewis

Ich habe bemerkt, dass api Beispielcode ein Beispiel für ein Balkendiagramm enthält, wobei der Wert des Balkens in jedem Balken angezeigt wird:

"""
========
Barchart
========

A bar plot with errorbars and height labels on individual bars
"""
import numpy as np
import matplotlib.pyplot as plt

N = 5
men_means = (20, 35, 30, 35, 27)
men_std = (2, 3, 4, 1, 2)

ind = np.arange(N)  # the x locations for the groups
width = 0.35       # the width of the bars

fig, ax = plt.subplots()
rects1 = ax.bar(ind, men_means, width, color='r', yerr=men_std)

women_means = (25, 32, 34, 20, 25)
women_std = (3, 5, 2, 3, 3)
rects2 = ax.bar(ind + width, women_means, width, color='y', yerr=women_std)

# add some text for labels, title and axes ticks
ax.set_ylabel('Scores')
ax.set_title('Scores by group and gender')
ax.set_xticks(ind + width / 2)
ax.set_xticklabels(('G1', 'G2', 'G3', 'G4', 'G5'))

ax.legend((rects1[0], rects2[0]), ('Men', 'Women'))


def autolabel(rects):
    """
    Attach a text label above each bar displaying its height
    """
    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')

autolabel(rects1)
autolabel(rects2)

plt.show()

ausgabe:

 enter image description here

Zu Ihrer Information Was ist die Höheneinheit in "barh" von Matplotlib? (Bis jetzt gibt es keine einfache Möglichkeit, eine feste Höhe für jeden Balken festzulegen)

17

Ich weiß, dass es ein alter Thread ist, aber ich bin mehrmals über Google hier gelandet und denke, dass keine Antwort wirklich befriedigend ist. Versuchen Sie es mit einer der folgenden Funktionen:

EDIT: Da ich einige Neigungen in diesem alten Thread bekomme, möchte ich auch eine aktualisierte Lösung freigeben (im Grunde füge ich meine beiden vorherigen Funktionen zusammen und entscheide automatisch, ob es sich um eine Balken- oder Hbar-Darstellung handelt):

def label_bars(ax, bars, text_format, **kwargs):
    """
    Attaches a label on every bar of a regular or horizontal bar chart
    """
    ys = [bar.get_y() for bar in bars]
    y_is_constant = all(y == ys[0] for y in ys)  # -> regular bar chart, since all all bars start on the same y level (0)

    if y_is_constant:
        _label_bar(ax, bars, text_format, **kwargs)
    else:
        _label_barh(ax, bars, text_format, **kwargs)


def _label_bar(ax, bars, text_format, **kwargs):
    """
    Attach a text label to each bar displaying its y value
    """
    max_y_value = ax.get_ylim()[1]
    inside_distance = max_y_value * 0.05
    outside_distance = max_y_value * 0.01

    for bar in bars:
        text = text_format.format(bar.get_height())
        text_x = bar.get_x() + bar.get_width() / 2

        is_inside = bar.get_height() >= max_y_value * 0.15
        if is_inside:
            color = "white"
            text_y = bar.get_height() - inside_distance
        else:
            color = "black"
            text_y = bar.get_height() + outside_distance

        ax.text(text_x, text_y, text, ha='center', va='bottom', color=color, **kwargs)


def _label_barh(ax, bars, text_format, **kwargs):
    """
    Attach a text label to each bar displaying its y value
    Note: label always outside. otherwise it's too hard to control as numbers can be very long
    """
    max_x_value = ax.get_xlim()[1]
    distance = max_x_value * 0.0025

    for bar in bars:
        text = text_format.format(bar.get_width())

        text_x = bar.get_width() + distance
        text_y = bar.get_y() + bar.get_height() / 2

        ax.text(text_x, text_y, text, va='center', **kwargs)

Jetzt können Sie sie für reguläre Balkendiagramme verwenden:

fig, ax = plt.subplots((5, 5))
bars = ax.bar(x_pos, values, width=0.5, align="center")
value_format = "{:.1%}"  # displaying values as percentage with one fractional digit
label_bars(ax, bars, value_format)

oder für horizontale Balkendiagramme:

fig, ax = plt.subplots((5, 5))
horizontal_bars = ax.barh(y_pos, values, width=0.5, align="center")
value_format = "{:.1%}"  # displaying values as percentage with one fractional digit
label_bars(ax, horizontal_bars, value_format)
8
SaturnFromTitan

Für jeden, der sein Label an der Basis seiner Balken haben möchte, einfach dividiere v durch den Wert des Labels:

for i, v in enumerate(labels):
    axes.text(i-.25, 
              v/labels[i]+100, 
              labels[i], 
              fontsize=18, 
              color=label_color_list[i])

(Anmerkung: Ich habe 100 hinzugefügt, damit es nicht ganz unten war)

Um ein Ergebnis wie dieses zu erhalten:  enter image description here

7
Skromak

Verwenden Sie plt.text () , um Text in den Plot einzufügen.

Beispiel:

import matplotlib.pyplot as plt
N = 5
menMeans = (20, 35, 30, 35, 27)
ind = np.arange(N)

#Creating a figure with some fig size
fig, ax = plt.subplots(figsize = (10,5))
ax.bar(ind,menMeans,width=0.4)
#Now the trick is here.
#plt.text() , you need to give (x,y) location , where you want to put the numbers,
#So here index will give you x pos and data+1 will provide a little gap in y axis.
for index,data in enumerate(menMeans):
    plt.text(x=index , y =data+1 , s=f"{data}" , fontdict=dict(fontsize=20))
plt.tight_layout()
plt.show()

Dies zeigt die Figur als:

Balkendiagramm mit Werten oben

1
Anirvan Sen

Für Pandas Menschen:

ax = s.plot(kind='barh') # s is a Series (float) in [0,1]
[ax.text(v, i, '{:.2f}%'.format(100*v)) for i, v in enumerate(s)];

Das ist es . Alternativ für diejenigen, die apply über Schleife mit Aufzählung ziehen

it = iter(range(len(s)))
s.apply(lambda x: ax.text(x, next(it),'{:.2f}%'.format(100*x)));

Außerdem gibt Ihnen ax.patches die Balken, die Sie mit ax.bar(...) erhalten würden. Falls Sie die Funktionen von @SaturnFromTitan oder Techniken anderer anwenden möchten.

1
tozCSS

Ich brauchte auch die Balkenbeschriftungen. Beachten Sie, dass meine y-Achse eine vergrößerte Ansicht mit Begrenzungen der y-Achse hat. Die Standardberechnungen zum Platzieren der Beschriftungen auf der Leiste funktionieren weiterhin mit der Höhe (use_global_coordinate = False im Beispiel). Ich wollte jedoch zeigen, dass die Beschriftungen in der vergrößerten Ansicht auch unter Verwendung der globalen Koordinaten in matplotlib 3.0.2 im unteren Teil der Grafik platziert werden können. Ich hoffe es hilft jemandem.

def autolabel(rects,data):
"""
Attach a text label above each bar displaying its height
"""
c = 0
initial = 0.091
offset = 0.205
use_global_coordinate = True

if use_global_coordinate:
    for i in data:        
        ax.text(initial+offset*c, 0.05, str(i), horizontalalignment='center',
                verticalalignment='center', transform=ax.transAxes,fontsize=8)
        c=c+1
else:
    for rect,i in Zip(rects,data):
        height = rect.get_height()
        ax.text(rect.get_x() + rect.get_width()/2., height,str(i),ha='center', va='bottom')

 Example output

0
Haramoz