Subplots en matplotlib

Los subplots permiten mostrar varios gráficos en una misma figura. La forma recomendada de crearlos en matplotlib es plt.subplots, que devuelve la figura y un array con un objeto de ejes para cada subplot.

Crear subplots con plt.subplots

Los argumentos nrows y ncols establecen el número de filas y columnas de la cuadrícula. Con una sola fila o columna los ejes se devuelven como un array unidimensional, por lo que puedes desempaquetarlos directamente.

Dos subplots uno al lado del otro en matplotlib

import numpy as np
import matplotlib.pyplot as plt

x = np.linspace(0, 10, 100)

fig, (ax1, ax2) = plt.subplots(nrows = 1, ncols = 2, figsize = (8, 3.5))

ax1.plot(x, np.sin(x))
ax2.plot(x, np.cos(x), color = "tab:orange")
# plt.show()

Cuadrícula de subplots

Con varias filas y columnas los ejes se devuelven como un array bidimensional. Accede a cada subplot con axs[fila, columna] o recórrelos todos con axs.flat.

import numpy as np
import matplotlib.pyplot as plt

rng = np.random.default_rng(1)

fig, axs = plt.subplots(2, 2)

axs[0, 0].plot(rng.normal(size = 20).cumsum())
axs[0, 1].bar(["A", "B", "C"], [3, 5, 2])
axs[1, 0].hist(rng.normal(size = 200))
axs[1, 1].scatter(rng.normal(size = 30), rng.normal(size = 30))
# plt.show()

Cuadrícula de 2x2 subplots en matplotlib

Recorrer los subplots

import numpy as np
import matplotlib.pyplot as plt

x = np.linspace(0, 10, 100)

fig, axs = plt.subplots(2, 3)

for i, ax in enumerate(axs.flat):
    ax.plot(x, np.sin(x + i))
    ax.set_title(f"Gráfico {i + 1}")

plt.tight_layout()
# plt.show()

Crear subplots con un bucle en matplotlib

Tamaño de la figura

El tamaño de toda la figura se establece en pulgadas con figsize = (ancho, alto). El espacio se reparte entre todos los subplots.

Cambiar el tamaño de los subplots en matplotlib

import numpy as np
import matplotlib.pyplot as plt

x = np.linspace(0, 10, 100)

fig, axs = plt.subplots(1, 3, figsize = (8, 3))

for ax in axs:
    ax.plot(x, np.sin(x))
# plt.show()

Espacio entre subplots

Los títulos y las etiquetas de los ejes suelen solaparse cuando hay varios subplots. La solución más sencilla es llamar a plt.tight_layout() o crear la figura con layout = "constrained", que ajustan el espaciado automáticamente.

import numpy as np
import matplotlib.pyplot as plt

x = np.linspace(0, 10, 100)

fig, axs = plt.subplots(2, 2, layout = "constrained")

for ax in axs.flat:
    ax.plot(x, np.sin(x))
    ax.set_title("Título")
    ax.set_xlabel("Etiqueta del eje X")
# plt.show()

Ajustar el espaciado de los subplots de matplotlib con constrained layout

Espaciado personalizado

Para establecer el espacio manualmente utiliza subplots_adjust, donde wspace y hspace son el espacio horizontal y vertical entre subplots como fracción del ancho y el alto medio de los ejes.

import numpy as np
import matplotlib.pyplot as plt

x = np.linspace(0, 10, 100)

fig, axs = plt.subplots(2, 2)

for ax in axs.flat:
    ax.plot(x, np.sin(x))

plt.subplots_adjust(wspace = 0.5, hspace = 0.5)
# plt.show()

Espacio personalizado entre subplots con subplots_adjust

Compartir ejes

Establece sharex = True o sharey = True para usar los mismos límites en todos los subplots. Las etiquetas de los ejes solo se muestran en los subplots exteriores, lo que ahorra espacio y facilita las comparaciones.

import numpy as np
import matplotlib.pyplot as plt

rng = np.random.default_rng(2)

fig, axs = plt.subplots(2, 2, sharex = True, sharey = True)

for ax in axs.flat:
    ax.hist(rng.normal(size = 200))
# plt.show()

Subplots con el eje Y compartido en matplotlib

Distintos anchos y altos

Los argumentos width_ratios y height_ratios establecen el tamaño relativo de las columnas y las filas de la cuadrícula.

import numpy as np
import matplotlib.pyplot as plt

rng = np.random.default_rng(3)
y = rng.normal(size = 300)

fig, (ax1, ax2) = plt.subplots(1, 2, sharey = True,
                               width_ratios = [3, 1])

ax1.plot(y)
ax2.hist(y, orientation = "horizontal")
# plt.show()

Subplots con distintos anchos en matplotlib

Diseños complejos con subplot_mosaic

Para diseños en los que un subplot ocupa varias filas o columnas utiliza subplot_mosaic. Cada letra del diseño es un subplot y repetir una letra hace que el subplot sea más grande. Los ejes se devuelven en un diccionario.

import numpy as np
import matplotlib.pyplot as plt

rng = np.random.default_rng(4)

fig, axd = plt.subplot_mosaic([["A", "A"],
                               ["B", "C"]],
                              layout = "constrained")

axd["A"].plot(rng.normal(size = 50).cumsum())
axd["B"].hist(rng.normal(size = 200))
axd["C"].scatter(rng.normal(size = 30), rng.normal(size = 30))
# plt.show()

Diseño complejo de subplots en matplotlib con subplot_mosaic

Títulos para cada subplot

Utiliza set_title en cada eje para agregar un título a cada subplot y fig.suptitle para agregar un título principal a la figura. Lee más sobre los títulos en matplotlib.

Títulos para los subplots y título de la figura en matplotlib

import numpy as np
import matplotlib.pyplot as plt

x = np.linspace(0, 10, 100)

fig, (ax1, ax2) = plt.subplots(1, 2, figsize = (8, 3.5))

ax1.plot(x, np.sin(x))
ax1.set_title("Seno")
ax2.plot(x, np.cos(x))
ax2.set_title("Coseno")

fig.suptitle("Funciones trigonométricas")
# plt.show()

Eliminar un subplot vacío

Si la cuadrícula tiene más celdas que gráficos, elimina las vacías con fig.delaxes u ocúltalas con ax.axis("off").

import numpy as np
import matplotlib.pyplot as plt

x = np.linspace(0, 10, 100)

fig, axs = plt.subplots(2, 2)

for i, ax in enumerate(axs.flat[:3]):
    ax.plot(x, np.sin(x + i))

fig.delaxes(axs[1, 1])
# plt.show()

Eliminar un subplot vacío en matplotlib

Para agregar una sola leyenda para todos los subplots consulta el tutorial sobre la leyenda en matplotlib.

Better Data Visualizations

A Guide for Scholars, Researchers, and Wonks

Comprar en Amazon
Storytelling con Datos

Visualización de datos para profesionales

Comprar en Amazon

También te puede interesar