franck dernoncourt
Generé un gráfico de barras, ¿cómo puedo mostrar el valor de la barra en cada barra?
Parcela 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
cphlewis
Actualización: ¡ahora hay un método incorporado para esto! Desplácese hacia abajo un par de respuestas a “Nuevo en matplotlib 3.4.0”.
Si no puede actualizar tanto, no se necesita mucho código. Agregar:
for i, v in enumerate(y):
ax.text(v + 3, i + .25, str(v), color="blue", fontweight="bold")
resultado:
Los valores de y v
son tanto la ubicación x como los valores de cadena para ax.text
y convenientemente el gráfico de barras tiene una métrica de 1 para cada barra, por lo que la enumeración i
es la ubicación y.
-
tal vez reemplace use va = ‘center’, en lugar de “i + .25” para la alineación horizontal
– Mathause
26/09/2017 a las 16:40
-
plt.text(v, i, " "+str(v), color='blue', va='center', fontweight='bold')
– Joao Cartucho
18 de abril de 2018 a las 11:41
-
¿Cómo puedo suprimir la salida de texto en un cuaderno jupyter? “;” al final no funciona.
– Ralf Hundewadt
17 de julio de 2019 a las 14:58
-
Si quiero imprimir BARRIO en la parte superior de la barra y lo mismo para todas las barras de baove, en lugar de a la izquierda, lo que hay que hacer. Probé y busqué en muchos lugares, pero no tengo ni idea hasta ahora.
–Rishi Bansal
19 de julio de 2019 a las 10:55
-
@RalfHundewadt acaba de poner un
plt.show()
cláusula al final. Por ejemplo:df.plot(); plt.show()
–Jairo Alves
14 oct 2019 a las 18:51
tdy
Nuevo en matplotlib 3.4.0
Ahora hay un incorporado Axes.bar_label
método auxiliar para autoetiquetar barras:
fig, ax = plt.subplots()
bars = ax.barh(indexes, values)
ax.bar_label(bars)
Tenga en cuenta que para los gráficos de barras agrupadas/apiladas, habrá varios contenedores de barras, a los que se puede acceder a través de ax.containers
:
for bars in ax.containers:
ax.bar_label(bars)
Más detalles:
- Cómo agregar separadores de miles (comas) a las etiquetas
- Cómo aplicar f-strings a las etiquetas
- Cómo agregar espaciado a las etiquetas
-
¡Por fin está ahí! ¡Una buena razón para actualizar a matplotlib 3.4.0!
– ilija139
19 de diciembre de 2022 a las 9:53
franck dernoncourt
Me he dado cuenta codigo de ejemplo 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()
producción:
FYI ¿Cuál es la unidad de variable de altura en “barh” de matplotlib? (a partir de ahora, no hay una manera fácil de establecer una altura fija para cada barra)
anirvan sen
Usar plt.text() para poner texto en la trama.
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:
Para cualquiera que quiera tener su etiqueta en la base de sus bares solo dividir v por el valor de la etiqueta como esto:
for i, v in enumerate(labels):
axes.text(i-.25,
v/labels[i]+100,
labels[i],
fontsize=18,
color=label_color_list[i])
(nota: agregué 100 para que no estuviera absolutamente en la parte inferior)
Sé que es un hilo antiguo, 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: Como estoy recibiendo algunos Me gusta en este hilo antiguo, también quiero compartir una solución actualizada (básicamente juntando mis dos funciones anteriores y decidiendo automáticamente si se trata de un diagrama de barra o hbar):
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)
Ahora puede usarlos para diagramas de barras regulares:
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)
o para gráficos de barras horizontales:
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)
tozCSS
Para los 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 todo. Alternativamente, para aquellos que prefieren apply
sobre bucle con enumerar:
it = iter(range(len(s)))
s.apply(lambda x: ax.text(x, next(it),'{:.2f}%'.format(100*x)));
También, ax.patches
te dará las barras que obtendrías con ax.bar(...)
. En caso de querer aplicar las funciones de @SaturnFromTitan o técnicas de otros.