python - example - ¿Cómo mostrar el valor de la barra en cada barra con pyplot.barh()?
matplotlib pyplot bar chart example (7)
Añadir:
for i, v in enumerate(y):
ax.text(v + 3, i + .25, str(v), color=''blue'', fontweight=''bold'')
resultado:
Los valores y
v
son tanto la ubicación x como los valores de cadena para
ax.text
, y convenientemente el diagrama de barras tiene una métrica de 1 para cada barra, por lo que la enumeración
i
es la ubicación y.
Generé un diagrama de barras, ¿cómo puedo mostrar el valor de la barra en cada barra?
Trama actual:
Lo que estoy tratando de conseguir:
Mi código:
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
He notado que el código de ejemplo de API contiene un ejemplo de gráfico de barras con el valor de la barra que se muestra en cada barra:
"""
========
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()
salida:
FYI ¿Cuál es la unidad de altura variable en "barh" de matplotlib? (a partir de ahora, no hay una manera fácil de establecer una altura fija para cada barra)
Para cualquiera que quiera tener su etiqueta en la base de sus barras, simplemente divida v por el valor de la etiqueta de esta manera:
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)
(nota: agregué 100, por lo que no estaba absolutamente en la parte inferior)
Para personas pandas:
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)];
Eso es.
Alternativamente, para aquellos que prefieren
apply
en lugar de bucle con enumerar:
it = iter(range(len(s)))
s.apply(lambda x: ax.text(x, next(it),''{:.2f}%''.format(100*x)));
Además,
ax.patches
te dará las barras que obtendrías con
ax.bar(...)
.
En caso de que desee aplicar las funciones de @SaturnFromTitan o las técnicas de otros.
Sé que es un hilo viejo, pero llegué aquí varias veces a través de Google y creo que ninguna respuesta dada es realmente satisfactoria todavía. Intente usar una de las siguientes funciones:
EDITAR : a medida que obtengo algunos ` ` me gusta '''' en este viejo hilo, también quiero compartir una solución actualizada (básicamente, uniendo mis dos funciones anteriores y decidiendo automáticamente si es un diagrama de barras o de barras):
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)
Ahora puede usarlos para gráficos de barras regulares:
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)
o para gráficos de barras horizontales:
for i, v in enumerate(labels):
axes.text(i-.25,
v/labels[i]+100,
labels[i],
fontsize=18,
color=label_color_list[i])
También necesitaba las etiquetas de barra, tenga en cuenta que mi eje y está teniendo una vista ampliada usando límites en el eje y. Los cálculos predeterminados para colocar las etiquetas en la parte superior de la barra todavía funcionan usando height (use_global_coordinate = False en el ejemplo). Pero quería mostrar que las etiquetas también se pueden colocar en la parte inferior del gráfico en una vista ampliada usando coordenadas globales en matplotlib 3.0.2 . Espero que ayude a alguien.
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'')
Use plt.text () para poner texto en el diagrama.
Ejemplo:
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()
Esto mostrará la figura como: