Skip to content

plt.savefig en Python: bbox_inches, DPI y etiquetas cortadas

Publicado el

Actualizado el

Referencia práctica de plt.savefig en Matplotlib: corrige etiquetas cortadas con bbox_inches='tight', ajusta DPI/formatos y evita imágenes en blanco tras plt.show().

Si necesitas guardar una figura con Matplotlib, empieza con fig.savefig("plot.png", dpi=300, bbox_inches="tight"). En los datos de búsqueda de esta página aparecen sobre todo consultas como plt.savefig, plt savefig, bbox_inches y plt.tight_layout() para que sirve, así que esta versión en español prioriza una referencia práctica, no una traducción larga de la documentación oficial.

Aquí verás cuándo usar bbox_inches='tight', cuándo conviene layout="constrained", cómo evitar imágenes en blanco después de plt.show(), y cómo elegir DPI, PNG, SVG o PDF.

Referencia rápida de savefig

fig.savefig(
    "plot.png",
    dpi=300,
    bbox_inches="tight",
    pad_inches=0.1,
)
ProblemaPrueba primero
Etiquetas, título o leyenda cortadosbbox_inches="tight"
Código nuevo de Matplotlibplt.subplots(layout="constrained")
Imagen guardada en blancoLlama a savefig() antes de plt.show()
Demasiado borde alrededorbbox_inches="tight", pad_inches=0
Imagen para informe o publicacióndpi=300 o SVG/PDF

Imagen en blanco después de plt.show(): guarda antes de mostrar

En muchos scripts, plt.show() puede cerrar o desregistrar la figura actual. Si llamas a plt.savefig() después, Matplotlib puede guardar una figura nueva y vacía.

fig, ax = plt.subplots()
ax.plot([1, 2, 3], [1, 4, 9])
fig.savefig("chart.png", dpi=300, bbox_inches="tight")
plt.show()

🧠 Por Qué Ocurre Esto

Matplotlib no amplía automáticamente el lienzo de la figura cuando las etiquetas se extienden más allá de los ejes. Las causas habituales incluyen:

  • Expresiones estilo LaTeX que generan símbolos altos
  • Valores grandes de fontsize
  • Etiquetas de ticks largas o rotadas
  • Cuadrículas de subplots muy ajustadas

Ejemplo:

matplotlib-savefig-label-clipping-example

import matplotlib.pyplot as plt
 
plt.figure()
plt.ylabel(r'$\ln\left(\frac{x_a-x_b}{x_a-x_c}\right)$')
plt.xlabel(r'$\ln\left(\frac{x_a-x_d}{x_a-x_e}\right)$', fontsize=50)
plt.title('Example with matplotlib 3.4.2\nLabel clipping example')
plt.show()

La etiqueta del eje Y es visible, pero la del eje X a menudo queda cortada en la figura guardada.


✅ 1. Mejor Solución Moderna (Recomendada): Usar layout="constrained"

En Matplotlib actual, una forma clara de activar el layout recomendado es:

fig, ax = plt.subplots(layout="constrained")

Ejemplo:

matplotlib-constrained-layout-example.png

fig, ax = plt.subplots(figsize=(7, 5), layout="constrained")
ax.set_xlabel("Very long bottom label that usually gets clipped", fontsize=16)
ax.set_ylabel("Tall math label:\n$\\frac{x_a - x_b}{x_c}$")
fig.savefig("figure.png")

✔ Ventajas

  • Moderno y estable
  • Funciona mejor que tight_layout()
  • Funciona bien con colorbars, leyendas y subplots

⚠ Inconvenientes

  • Un poco más lento en cuadrículas grandes de subplots

Si estás escribiendo código nuevo con Matplotlib, esta debería ser tu opción por defecto.


✅ 2. Ajustar Márgenes Manualmente con subplots_adjust

Sigue siendo un método sencillo y efectivo:

plt.subplots_adjust(bottom=0.15)

O sobre la figura:

plt.gcf().subplots_adjust(bottom=0.18)

Aumenta el valor del margen hasta que las etiquetas dejen de solaparse o cortarse.

matplotlib-subplots-adjust-margins.png


✅ 3. Usar tight_layout() (Más Antiguo pero Aún Útil)

tight_layout() ajusta automáticamente el relleno:

fig, axes = plt.subplots(ncols=2, nrows=2, figsize=(8, 6))
for ax in axes.flatten():
    ax.set_xlabel("Example X label")
    ax.set_ylabel("Example Y label")
 
plt.tight_layout()
plt.show()

Notas

  • Bueno para gráficas sencillas
  • Puede tener problemas con leyendas y colorbars
  • layout="constrained" es ahora la solución preferida

✅ 4. Guardar con bbox_inches="tight" (Muy Buen Arreglo Rápido)

Una solución muy usada para el recorte:

plt.savefig("myfile.png", bbox_inches="tight")

Cuándo usarlo

  • Arreglo rápido sin modificar el layout
  • Asegura que todo lo que aparece en pantalla también aparezca en el archivo

matplotlib-tight-layout-subplots.png


✅ 5. Activar Distribución Automática con rcParams

Si quieres una solución permanente que se aplique a todas las gráficas: matplotlib-bbox-inches-tight-example.png

Actualizar rcParams en tiempo de ejecución:

from matplotlib import rcParams
rcParams.update({"figure.autolayout": True})

O configurar matplotlibrc:

figure.autolayout : True

Esto ayuda a garantizar resultados consistentes entre distintas máquinas.


📌 Tabla Resumen: ¿Qué Método Debería Usar?

MétodoCuándo UsarloMejor Para
layout="constrained"Opción por defectoLayout moderno, subplots, leyendas
bbox_inches='tight'Arreglo rápido al guardarExportar gráficas individuales
tight_layout()Código legadoCuadrículas simples de subplots
subplots_adjust()Quieres control totalmente manualAjuste fino para publicaciones
figure.autolayout=TrueValor por defecto a nivel proyectoConsistencia entre distintos sistemas

💡 Consejos Extra para Figuras Perfectas

✔ Usar mayor DPI para reducir problemas con etiquetas largas

plt.savefig("fig.png", dpi=200, bbox_inches="tight")

✔ Evitar tamaños de fuente enormes salvo que sean necesarios

Las fuentes muy grandes aumentan la probabilidad de recorte.

✔ Para colorbars: usa constrained_layout

Funciona notablemente mejor que tight_layout.


📊 Crea Visualizaciones sin Ajustar Layout Manualmente (PyGWalker)

Si usas Matplotlib principalmente para visualizar DataFrames, puede que no necesites ajustar layouts manualmente.

Puedes simplemente:

  • Cargar tu DataFrame
  • Arrastrar y soltar campos
  • Generar gráficas al instante

Usando PyGWalker, una herramienta de visualización open-source:

PyGWalker for Data visualization (opens in a new tab)

Así se usa:

pip install pygwalker
import pygwalker as pyg
gwalker = pyg.walk(df)

O pruébalo online:

KaggleGoogle ColabGitHub

Preguntas frecuentes

  1. ¿Cómo uso plt.savefig para que no corte etiquetas? Guarda con bbox_inches='tight': plt.savefig("plot.png", dpi=300, bbox_inches="tight"). Para código nuevo, crea la figura con layout="constrained".

  2. ¿Para qué sirve bbox_inches="tight"? Recalcula el área que se guarda para incluir etiquetas, títulos, leyendas y anotaciones que quedan fuera de los ejes.

  3. ¿Cuándo conviene layout="constrained" en vez de bbox_inches='tight'? Usa layout="constrained" al crear figuras nuevas, sobre todo con subplots, colorbars o leyendas. Usa bbox_inches='tight' como arreglo rápido en el momento de exportar.

  4. ¿Por qué plt.savefig guarda una imagen en blanco después de plt.show()? En algunos backends, plt.show() cierra o desregistra la figura actual. Guarda primero con fig.savefig(...) o plt.savefig(...), y después llama a plt.show().

  5. ¿Qué DPI debería usar en savefig? Usa 150 DPI para web o presentaciones, 300 DPI para informes e impresión, y SVG/PDF si necesitas gráficos vectoriales.

Guías relacionadas