Matplotlib Pyplot
Aprende cómo funciona matplotlib.pyplot: interfaz con estado, funciones clave, conceptos de figura y ejes, guardar gráficos y cuándo usar la API orientada a objetos.
matplotlib.pyplot es una colección de funciones que hacen que Matplotlib se comporte como el sistema de gráficos de MATLAB. Cada función crea o modifica algún elemento de una figura — añadiendo ejes, dibujando una línea, estableciendo un título — y pyplot realiza un seguimiento automático de la figura y los ejes "actuales" para que no tengas que pasar objetos manualmente. Esta página explica cómo funciona ese modelo con estado, recorre las funciones pyplot más importantes y muestra cuándo conviene cambiar a la API explícita orientada a objetos.
¿Qué es matplotlib.pyplot?
Matplotlib tiene dos interfaces principales:
| Interfaz | Cómo acceder | Más adecuada para |
|---|---|---|
| pyplot (con estado) | import matplotlib.pyplot as plt | Scripts rápidos, notebooks interactivos |
| Orientada a objetos | fig, ax = plt.subplots() | Figuras complejas con múltiples paneles, bibliotecas, código reutilizable |
Ambas interfaces viven en la misma biblioteca. pyplot es una capa de conveniencia — cada llamada a plt.algo() manipula en última instancia los mismos objetos Figure y Axes que la interfaz OO expone directamente. Entender esta relación te permite mezclar ambos estilos con confianza.
El alias estándar es plt:
import matplotlib.pyplot as pltCómo funciona la interfaz con estado
pyplot mantiene una referencia interna a la figura actual y los ejes actuales. Cuando llamas a plt.plot(), Matplotlib:
- Comprueba si ya existe una figura; si no, crea una.
- Comprueba si esa figura tiene ejes; si no, añade un único
Axesque ocupe la figura. - Dibuja los datos en esos ejes.
import matplotlib.pyplot as plt
# No figure exists yet — pyplot creates one automatically
plt.plot([1, 2, 3], [4, 6, 5])
plt.title("My first plot")
plt.show()La figura y los ejes se crearon de forma implícita. Esto es conveniente para gráficos puntuales, pero puede causar sorpresas cuando ejecutas múltiples gráficos en el mismo script. Usa plt.figure() y plt.clf() (limpiar figura) o plt.close() para controlar el estado de forma explícita.
Funciones principales de pyplot
plt.plot() — Dibujar líneas y marcadores
plt.plot(x, y) es la función base. Dibuja líneas, marcadores o ambos.
import matplotlib.pyplot as plt
months = [1, 2, 3, 4, 5, 6]
revenue = [12000, 15000, 13500, 17000, 19500, 22000]
plt.plot(months, revenue, color="steelblue", linewidth=2, marker="o", markersize=6)
plt.xlabel("Month")
plt.ylabel("Revenue ($)")
plt.title("Monthly Revenue")
plt.grid(True, linestyle="--", alpha=0.5)
plt.show()Parámetros clave de plt.plot():
| Parámetro | Valores de ejemplo | Efecto |
|---|---|---|
color | "red", "#2196F3", (0.1, 0.6, 0.8) | Color de la línea y el marcador |
linewidth / lw | 1, 2.5 | Grosor de la línea |
linestyle / ls | "-", "--", ":", "-." | Sólida, discontinua, punteada, guión-punto |
marker | "o", "s", "^", "x" | Círculo, cuadrado, triángulo, cruz |
markersize / ms | 4, 8 | Tamaño del marcador en puntos |
label | "Series A" | Texto usado por plt.legend() |
plt.xlabel(), plt.ylabel(), plt.title()
Etiquetan los ejes y añaden un título. Los tres aceptan el argumento fontsize:
import matplotlib.pyplot as plt
plt.plot([0, 1, 2], [0, 1, 4])
plt.xlabel("x", fontsize=12)
plt.ylabel("x²", fontsize=12)
plt.title("Quadratic Growth", fontsize=14, fontweight="bold")
plt.show()plt.legend()
Cuando pasas label= a una llamada de gráfico, plt.legend() convierte esas etiquetas en un cuadro sobre el gráfico:
import matplotlib.pyplot as plt
x = [1, 2, 3, 4, 5]
plt.plot(x, [v**1 for v in x], label="Linear")
plt.plot(x, [v**2 for v in x], label="Quadratic")
plt.plot(x, [v**3 for v in x], label="Cubic")
plt.xlabel("x")
plt.ylabel("y")
plt.title("Growth Rates")
plt.legend()
plt.show()Controla la posición de la leyenda con el parámetro loc: "upper left", "lower right", "best" (valor por defecto), entre otros.
plt.grid()
plt.grid(True) añade líneas de cuadrícula. Usa axis="x" o axis="y" para restringirlas a un eje, y pasa linestyle / alpha para darles estilo:
plt.grid(True, axis="y", linestyle="--", alpha=0.7)plt.xlim() y plt.ylim()
Establecen el rango visible en cada eje:
import matplotlib.pyplot as plt
plt.plot([1, 2, 3, 4, 5], [2, 4, 1, 5, 3])
plt.xlim(0, 6) # show a bit of padding on each side
plt.ylim(0, 7)
plt.show()plt.xticks() y plt.yticks()
Controlan qué marcas de graduación aparecen y qué etiquetas llevan:
import matplotlib.pyplot as plt
plt.plot([0, 1, 2, 3, 4], [10, 20, 15, 25, 30])
plt.xticks([0, 1, 2, 3, 4], ["Mon", "Tue", "Wed", "Thu", "Fri"])
plt.yticks([10, 20, 30], ["Low", "Mid", "High"])
plt.show()plt.figure()
Crea una nueva figura de forma explícita. Esto es importante en scripts que producen múltiples gráficos separados:
import matplotlib.pyplot as plt
plt.figure(figsize=(8, 4)) # width, height in inches
plt.plot([1, 2, 3], [3, 1, 4])
plt.title("Figure with custom size")
plt.show()figsize controla el tamaño de salida. Una figura más ancha (p. ej. (12, 4)) es adecuada para datos de series temporales; una figura cuadrada es mejor para gráficos de dispersión.
plt.savefig()
Guarda la figura actual en un archivo en lugar de (o además de) mostrarla:
import matplotlib.pyplot as plt
plt.plot([1, 2, 3], [1, 4, 9])
plt.title("Saved Plot")
plt.savefig("output.png", dpi=150, bbox_inches="tight")
plt.show()Los formatos compatibles incluyen png, pdf, svg y jpg. bbox_inches="tight" recorta el espacio en blanco extra alrededor de la figura. Llama a savefig() antes de show() — show() borra el estado de la figura en algunos backends.
plt.close() y plt.clf()
En un bucle que produce muchas figuras, cierra siempre las figuras que ya no necesites para liberar memoria:
plt.close() # close the current figure
plt.close("all") # close every open figure
plt.clf() # clear the current figure without closing its windowSubgráficos con pyplot
plt.subplots() es el puente entre las interfaces pyplot y OO. Crea un objeto Figure y uno o más objetos Axes, y devuelve ambos:
import matplotlib.pyplot as plt
fig, axes = plt.subplots(1, 2, figsize=(10, 4)) # 1 row, 2 columns
# Left panel
axes[0].plot([1, 2, 3], [1, 4, 9], color="steelblue")
axes[0].set_title("Quadratic")
axes[0].set_xlabel("x")
axes[0].set_ylabel("x²")
# Right panel
axes[1].plot([1, 2, 3], [1, 8, 27], color="tomato")
axes[1].set_title("Cubic")
axes[1].set_xlabel("x")
axes[1].set_ylabel("x³")
fig.suptitle("Growth Curves", fontsize=14)
plt.tight_layout()
plt.show()plt.tight_layout() ajusta automáticamente el espaciado entre paneles para evitar que los títulos y las etiquetas se superpongan.
pyplot vs. la API orientada a objetos
Una vez que superas un único eje, la API con estado se vuelve más difícil de razonar. Usa la API OO (mediante fig, ax = plt.subplots()) cuando:
- Tienes más de un subgráfico.
- Estás escribiendo una función que crea y devuelve un gráfico.
- Necesitas un control detallado sobre formateadores de marcas, ejes secundarios o ejes insertados.
| Tarea | Estilo pyplot | Estilo OO |
|---|---|---|
| Establecer título | plt.title("...") | ax.set_title("...") |
| Establecer etiqueta x | plt.xlabel("...") | ax.set_xlabel("...") |
| Establecer límites x | plt.xlim(0, 10) | ax.set_xlim(0, 10) |
| Dibujar una línea | plt.plot(x, y) | ax.plot(x, y) |
El patrón es sencillo: la mayoría de las funciones plt.algo() tienen un equivalente ax.set_algo() en el objeto Axes.
Un ejemplo completo
El siguiente script combina las funciones pyplot más comunes en un ejemplo completo y ejecutable:
import matplotlib.pyplot as plt
# Data
years = [2019, 2020, 2021, 2022, 2023]
product_a = [45, 38, 52, 61, 70]
product_b = [30, 42, 39, 55, 65]
# Figure
plt.figure(figsize=(9, 5))
# Two series
plt.plot(years, product_a, marker="o", color="steelblue",
linewidth=2, label="Product A")
plt.plot(years, product_b, marker="s", color="tomato",
linewidth=2, label="Product B")
# Labels and decoration
plt.xlabel("Year", fontsize=12)
plt.ylabel("Units Sold (thousands)", fontsize=12)
plt.title("Annual Sales Comparison", fontsize=14)
plt.legend()
plt.grid(True, linestyle="--", alpha=0.5)
plt.xticks(years)
# Save and display
plt.savefig("sales_comparison.png", dpi=150, bbox_inches="tight")
plt.show()Este ejemplo muestra ambas series en los mismos ejes, una leyenda, cuadrícula, etiquetas personalizadas en el eje x, y guarda el resultado en un archivo PNG.
Errores comunes
Olvidar plt.show() — en un script Python normal (no en Jupyter), la ventana del gráfico nunca se abre sin él. En Jupyter, %matplotlib inline lo hace automático.
Llamar a plt.savefig() después de plt.show() — show() finaliza y reinicia la figura. Guarda primero y luego muestra:
plt.savefig("chart.png") # correct order
plt.show()Acumulación de múltiples figuras — en un bucle, cada llamada a plt.figure() crea una nueva figura que permanece en memoria hasta que llamas a plt.close(). Cierra las figuras que ya no necesites.
Mezclar estilos pyplot y OO de forma inconsistente — está bien usar ambos, pero hazlo de manera deliberada: obtén el objeto Axes y trabaja con él directamente en lugar de depender de los "ejes actuales" implícitos de pyplot cuando tienes más de un eje.
Próximos pasos
- Gráficos de líneas con Matplotlib — estilos de línea, múltiples series y áreas rellenas en profundidad.
- Marcadores de Matplotlib — todas las formas de marcador integradas y cómo darles estilo.
- Etiquetas de Matplotlib — títulos, etiquetas de ejes, anotaciones y colocación de texto.
- Cuadrícula de Matplotlib — estilos de líneas de cuadrícula, marcas secundarias y estilo del fondo.
- Barras de Matplotlib — gráficos de barras verticales, horizontales, apiladas y agrupadas.
- Dispersión en Matplotlib — gráficos de dispersión con mapas de color y codificación por tamaño.
- Histogramas de Matplotlib — control de intervalos, curvas de densidad y distribuciones superpuestas.
- Subgráfico de Matplotlib — diseños multipanel con
subplots()yGridSpec.