Ich habe ein Balkendiagramm erstellt. Wie kann ich den Wert des Balkens in jedem Balken anzeigen?
Aktuelle Handlung:
Was ich versuche zu bekommen:
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
Hinzufügen:
for i, v in enumerate(y):
ax.text(v + 3, i + .25, str(v), color='blue', fontweight='bold')
ergebnis:
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.
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:
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)
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)
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)
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:
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.
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')