W3docs

Gráficos de barras con Matplotlib en Python — Guía completa

Aprende a crear gráficos de barras verticales, horizontales, agrupados y apilados en Python con Matplotlib. Incluye ejemplos de color, ancho, barras de error y guardado.

Las funciones bar() y barh() de Matplotlib permiten construir gráficos de barras que comparan cantidades entre categorías. Este capítulo cubre desde el gráfico de una sola serie más sencillo hasta diseños agrupados y apilados, con opciones de personalización prácticas que necesitarás en proyectos reales: colores, ancho de barra, estilo de bordes, barras de error y cómo guardar el resultado en un archivo.

Antes de comenzar, asegúrate de tener Matplotlib instalado:

pip install matplotlib

Si eres nuevo en la biblioteca, consulta primero los capítulos de Introducción a Matplotlib y Primeros pasos.

¿Qué es un gráfico de barras?

Un gráfico de barras usa barras rectangulares cuya longitud codifica un valor numérico, lo que facilita comparar cantidades entre categorías discretas — por ejemplo, ingresos mensuales, población por país o puntuaciones de exámenes por asignatura.

Usa un gráfico de barras cuando:

  • Estés comparando una única métrica entre categorías (gráfico de barras simple).
  • Quieras mostrar cómo se desglosa un total en partes (gráfico de barras apiladas).
  • Necesites comparar múltiples métricas lado a lado para las mismas categorías (gráfico de barras agrupadas).
  • Las etiquetas de categorías son largas y se leen mejor en horizontal (gráfico de barras horizontal).

Crear un gráfico de barras vertical básico

La función plt.bar(x, height) recibe una secuencia de etiquetas de categoría (o posiciones numéricas) y una secuencia equivalente de alturas de barra.

import matplotlib.pyplot as plt

categories = ['A', 'B', 'C', 'D', 'E']
values     = [10, 24, 36, 40, 15]

plt.bar(categories, values)

plt.title('Sample Bar Chart')
plt.xlabel('Category')
plt.ylabel('Value')

plt.tight_layout()
plt.show()

plt.tight_layout() evita que las etiquetas de los ejes queden recortadas — es un buen hábito añadirlo antes de cada llamada a show() o savefig().

Personalizar la apariencia de las barras

Color

Pasa un nombre de color, una cadena hexadecimal o una lista de colores por barra al parámetro color:

import matplotlib.pyplot as plt

categories = ['A', 'B', 'C', 'D', 'E']
values     = [10, 24, 36, 40, 15]

# One color for all bars
plt.bar(categories, values, color='steelblue')

plt.title('Steelblue Bars')
plt.xlabel('Category')
plt.ylabel('Value')
plt.tight_layout()
plt.show()

Para colorear cada barra de forma distinta, pasa una lista:

import matplotlib.pyplot as plt

categories = ['A', 'B', 'C', 'D', 'E']
values     = [10, 24, 36, 40, 15]
colors     = ['#e74c3c', '#3498db', '#2ecc71', '#f39c12', '#9b59b6']

plt.bar(categories, values, color=colors)

plt.title('Multi-Color Bar Chart')
plt.xlabel('Category')
plt.ylabel('Value')
plt.tight_layout()
plt.show()

Ancho de barra y color de borde

El width predeterminado es 0.8 (80 % del espacio entre posiciones de marcas). Redúcelo para un aspecto más ligero o auméntalo para ocupar más espacio. edgecolor dibuja un contorno alrededor de cada barra:

import matplotlib.pyplot as plt

categories = ['A', 'B', 'C', 'D', 'E']
values     = [10, 24, 36, 40, 15]

plt.bar(
    categories, values,
    width=0.5,
    color='cornflowerblue',
    edgecolor='navy',
    linewidth=1.2,
)

plt.title('Custom Width and Edge')
plt.xlabel('Category')
plt.ylabel('Value')
plt.tight_layout()
plt.show()

Añadir una leyenda

Pasa una cadena label a bar() y luego llama a plt.legend():

import matplotlib.pyplot as plt

categories = ['A', 'B', 'C', 'D', 'E']
values     = [10, 24, 36, 40, 15]

plt.bar(categories, values, color='teal', label='2024 Sales')
plt.legend()

plt.title('Bar Chart with Legend')
plt.xlabel('Category')
plt.ylabel('Value')
plt.tight_layout()
plt.show()

Rotar las etiquetas de las marcas

Los nombres de categoría largos se superponen a menos que los rotes con plt.xticks(rotation=...):

import matplotlib.pyplot as plt

months = ['January', 'February', 'March', 'April', 'May', 'June']
sales  = [120, 95, 140, 160, 130, 175]

plt.bar(months, sales, color='darkorange')
plt.xticks(rotation=45, ha='right')   # ha='right' aligns the labels nicely

plt.title('Monthly Sales')
plt.xlabel('Month')
plt.ylabel('Units Sold')
plt.tight_layout()
plt.show()

Gráficos de barras horizontales

plt.barh(y, width) dibuja barras que se extienden horizontalmente. Es especialmente útil cuando las etiquetas de categoría son largas, ya que aparecen en el eje y con bastante espacio horizontal.

import matplotlib.pyplot as plt

languages  = ['Python', 'JavaScript', 'Java', 'C#', 'TypeScript']
popularity = [30.3, 25.1, 17.8, 12.4, 9.6]

plt.barh(languages, popularity, color='mediumseagreen')

plt.title('Programming Language Popularity (%)')
plt.xlabel('Share (%)')
plt.ylabel('Language')
plt.tight_layout()
plt.show()

Consejo: ordena los datos antes de graficar para que la categoría más popular aparezca en la parte superior:

import matplotlib.pyplot as plt

languages  = ['Python', 'JavaScript', 'Java', 'C#', 'TypeScript']
popularity = [30.3, 25.1, 17.8, 12.4, 9.6]

# Sort ascending so the highest bar ends up at the top after barh reversal
pairs      = sorted(zip(popularity, languages))
popularity_sorted, languages_sorted = zip(*pairs)

plt.barh(languages_sorted, popularity_sorted, color='mediumseagreen')

plt.title('Programming Language Popularity (sorted)')
plt.xlabel('Share (%)')
plt.tight_layout()
plt.show()

Gráficos de barras agrupadas

Un gráfico de barras agrupadas (una al lado de la otra) compara dos o más series para el mismo conjunto de categorías. Matplotlib no tiene una función dedicada para esto — se crea desplazando las posiciones x de cada serie usando NumPy:

import matplotlib.pyplot as plt
import numpy as np

categories = ['Q1', 'Q2', 'Q3', 'Q4']
sales_2023 = [120, 135, 150, 170]
sales_2024 = [140, 160, 145, 195]

x     = np.arange(len(categories))  # [0, 1, 2, 3]
width = 0.35                         # width of each individual bar

fig, ax = plt.subplots()

bars1 = ax.bar(x - width / 2, sales_2023, width, label='2023', color='steelblue')
bars2 = ax.bar(x + width / 2, sales_2024, width, label='2024', color='darkorange')

ax.set_title('Quarterly Sales Comparison')
ax.set_xlabel('Quarter')
ax.set_ylabel('Units Sold')
ax.set_xticks(x)
ax.set_xticklabels(categories)
ax.legend()

plt.tight_layout()
plt.show()

Puntos clave:

  • x - width / 2 desplaza la primera serie hacia la izquierda; x + width / 2 desplaza la segunda hacia la derecha, de modo que las barras quedan una al lado de la otra.
  • ax.set_xticks(x) y ax.set_xticklabels(categories) colocan las etiquetas de categoría en el centro de cada grupo.
  • La API orientada a objetos (fig, ax = plt.subplots()) es preferible para los gráficos agrupados porque ofrece control explícito sobre cada eje.

Añadir etiquetas de valor sobre las barras

Puedes anotar cada barra con su valor usando ax.bar_label() (añadido en Matplotlib 3.4):

import matplotlib.pyplot as plt
import numpy as np

categories = ['Q1', 'Q2', 'Q3', 'Q4']
sales_2023 = [120, 135, 150, 170]
sales_2024 = [140, 160, 145, 195]

x     = np.arange(len(categories))
width = 0.35

fig, ax = plt.subplots()
bars1 = ax.bar(x - width / 2, sales_2023, width, label='2023', color='steelblue')
bars2 = ax.bar(x + width / 2, sales_2024, width, label='2024', color='darkorange')

ax.bar_label(bars1, padding=3)
ax.bar_label(bars2, padding=3)

ax.set_title('Quarterly Sales with Labels')
ax.set_xlabel('Quarter')
ax.set_ylabel('Units Sold')
ax.set_xticks(x)
ax.set_xticklabels(categories)
ax.legend()

plt.tight_layout()
plt.show()

Gráficos de barras apiladas

Un gráfico de barras apiladas coloca las series una encima de la otra, mostrando cómo las partes individuales contribuyen al total. Usa el parámetro bottom para indicarle a Matplotlib dónde debe comenzar cada serie:

import matplotlib.pyplot as plt
import numpy as np

categories = ['A', 'B', 'C', 'D', 'E']
series1    = [10, 24, 36, 40, 15]
series2    = [ 5, 12, 15, 20, 10]
series3    = [ 8,  6, 10, 12,  7]

x = np.arange(len(categories))

plt.bar(x, series1, label='Group 1', color='steelblue')
plt.bar(x, series2, label='Group 2', color='darkorange',
        bottom=series1)
plt.bar(x, series3, label='Group 3', color='seagreen',
        bottom=np.array(series1) + np.array(series2))

plt.xticks(x, categories)
plt.title('Stacked Bar Chart')
plt.xlabel('Category')
plt.ylabel('Total Value')
plt.legend()
plt.tight_layout()
plt.show()

El bottom de la tercera serie es la suma elemento a elemento de las dos primeras, de modo que cada barra comienza exactamente donde terminó la anterior. Usar np.array() hace que la suma funcione correctamente con listas.

Barras de error

Cuando tus datos tienen incertidumbre o variabilidad (por ejemplo, desviación estándar entre mediciones repetidas), añade barras de error con el parámetro yerr:

import matplotlib.pyplot as plt
import numpy as np

categories    = ['Control', 'Treatment A', 'Treatment B', 'Treatment C']
means         = [5.2, 7.8, 6.1, 9.4]
std_devs      = [0.5, 0.8, 0.6, 1.1]

plt.bar(
    categories, means,
    yerr=std_devs,
    capsize=5,           # width of the error bar caps
    color='cornflowerblue',
    edgecolor='black',
    linewidth=0.8,
)

plt.title('Experimental Results with Error Bars')
plt.xlabel('Group')
plt.ylabel('Mean Value')
plt.tight_layout()
plt.show()

capsize controla las tapas horizontales en la parte superior e inferior de cada barra de error; un valor de 4–6 suele ser legible.

Guardar un gráfico de barras en un archivo

Usa plt.savefig() en lugar de plt.show() (o llámalo antes de show()). Puedes especificar el formato mediante la extensión del archivo:

import matplotlib.pyplot as plt

categories = ['A', 'B', 'C', 'D', 'E']
values     = [10, 24, 36, 40, 15]

plt.bar(categories, values, color='steelblue')
plt.title('Saved Bar Chart')
plt.xlabel('Category')
plt.ylabel('Value')
plt.tight_layout()

# Save as PNG at 150 dpi
plt.savefig('bar_chart.png', dpi=150)

# Save as vector PDF (ideal for publications)
plt.savefig('bar_chart.pdf')

plt.show()

Opciones de formato habituales: png, pdf, svg, eps. Usa svg o pdf cuando necesites una imagen escalable lista para imprimir.

Controlar el tamaño de la figura

De forma predeterminada, Matplotlib crea una figura de 6,4 × 4,8 pulgadas. Pasa figsize=(width, height) a plt.figure() o plt.subplots() para cambiarlo:

import matplotlib.pyplot as plt

categories = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun',
              'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']
values     = [80, 70, 95, 110, 130, 150, 160, 155, 120, 100, 85, 90]

fig, ax = plt.subplots(figsize=(12, 5))  # wider figure for 12 months
ax.bar(categories, values, color='tomato')
ax.set_title('Monthly Data')
ax.set_xlabel('Month')
ax.set_ylabel('Value')

plt.tight_layout()
plt.savefig('monthly_bar_chart.png', dpi=150)
plt.show()

Referencia rápida

TareaCódigo
Gráfico de barras verticalplt.bar(x, y)
Gráfico de barras horizontalplt.barh(y, width)
Cambiar colorplt.bar(x, y, color='steelblue')
Cambiar anchoplt.bar(x, y, width=0.5)
Barras apiladasplt.bar(x, y2, bottom=y1)
Barras de errorplt.bar(x, y, yerr=errors, capsize=5)
Añadir etiquetas de valorax.bar_label(bars, padding=3)
Rotar etiquetas del eje xplt.xticks(rotation=45, ha='right')
Guardar en archivoplt.savefig('file.png', dpi=150)

Capítulos relacionados

Was this page helpful?