Skip to content

plt.savefig en Python : bbox_inches, DPI et labels coupés

Publié le

Mis à jour le

Référence pratique Matplotlib savefig : corriger les labels coupés avec bbox_inches='tight', régler DPI/PNG/SVG/PDF et éviter une image vide après plt.show().

Pour enregistrer rapidement une figure Matplotlib, commencez par fig.savefig("plot.png", dpi=300, bbox_inches="tight"). Les requêtes qui exposent cette page en français sont surtout plt.savefig, plt savefig, savefig et bbox_inches; cette version privilégie donc une fiche de dépannage concrète plutôt qu’un résumé générique de la documentation.

Elle couvre les labels coupés, bbox_inches='tight', layout="constrained", les images vides après plt.show(), le DPI et les formats PNG/SVG/PDF.

Référence rapide savefig

fig.savefig(
    "plot.png",
    dpi=300,
    bbox_inches="tight",
    pad_inches=0.1,
)
ProblèmeÀ essayer d’abord
Labels, titre ou légende coupésbbox_inches="tight"
Nouveau code Matplotlibplt.subplots(layout="constrained")
Image enregistrée videAppeler savefig() avant plt.show()
Trop de marge autour du graphebbox_inches="tight", pad_inches=0
Image haute résolutiondpi=300 ou SVG/PDF

Image vide après plt.show() : sauvegarder avant d’afficher

Dans de nombreux scripts, plt.show() peut fermer la figure ou la désenregistrer de pyplot. Si vous appelez plt.savefig() ensuite, Matplotlib peut enregistrer une nouvelle figure vide.

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

🧠 Pourquoi ce problème apparaît

Matplotlib n’agrandit pas automatiquement la zone de la figure lorsque les labels dépassent des axes. Les causes courantes incluent :

  • Des expressions de style LaTeX qui produisent des symboles très hauts
  • Des valeurs de fontsize importantes
  • Des labels de graduations longs ou pivotés
  • Des grilles de sous-graphiques très serrées

Exemple :

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()

Le label de l’axe Y est visible, mais celui de l’axe X sera souvent coupé dans la figure sauvegardée.


✅ 1. Meilleure solution moderne (recommandée) : utiliser layout="constrained"

Dans Matplotlib actuel, une manière claire d’activer la mise en page recommandée est :

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

Exemple :

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")

✔ Avantages

  • Moderne et stable
  • Fonctionne mieux que tight_layout()
  • Gère bien colorbars, légendes et sous-graphiques

⚠ Inconvénients

  • Légèrement plus lent sur de grandes grilles de sous-graphiques

Si vous écrivez du nouveau code Matplotlib, cela devrait être votre choix par défaut.


✅ 2. Ajuster les marges manuellement avec subplots_adjust

Une méthode toujours simple et efficace :

plt.subplots_adjust(bottom=0.15)

Ou directement sur la figure :

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

Augmentez la valeur de marge jusqu’à ce que les labels ne se chevauchent plus.

matplotlib-subplots-adjust-margins.png


✅ 3. Utiliser tight_layout() (plus ancien mais encore utile)

tight_layout() ajuste automatiquement les espacements :

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()

Remarques

  • Bon pour les graphiques simples
  • Peut mal gérer les légendes et colorbars
  • layout="constrained" est maintenant la solution à privilégier

✅ 4. Sauvegarder avec bbox_inches="tight" (excellent correctif rapide)

Une solution très utilisée contre le rognage :

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

Quand l’utiliser

  • Correctif rapide sans modifier la mise en page
  • Garantit que tout ce qui apparaît à l’écran apparaît aussi dans le fichier

matplotlib-tight-layout-subplots.png


✅ 5. Activer la mise en page automatique avec rcParams

Si vous voulez une solution permanente qui s’applique à tous les graphiques : matplotlib-bbox-inches-tight-example.png

Mettre à jour rcParams à l’exécution :

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

OU configurer matplotlibrc :

figure.autolayout : True

Cela aide à garantir un rendu cohérent entre différentes machines.


📌 Tableau récapitulatif : quelle méthode utiliser ?

MéthodeQuand l’utiliserIdéal pour
layout="constrained"Choix par défautMise en page moderne, subplots, légendes
bbox_inches='tight'Correctif rapide lors de la sauvegardeExport de graphiques simples
tight_layout()Code existant / héritéGrilles de sous-graphiques simples
subplots_adjust()Vous voulez un contrôle manuel totalAjustements de type publication
figure.autolayout=TrueValeur par défaut à l’échelle d’un projetCohérence entre systèmes

💡 Conseils supplémentaires pour des figures impeccables

✔ Utiliser un DPI plus élevé pour réduire les découpes avec des labels longs

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

✔ Éviter les tailles de police énormes sauf nécessité

Des polices très grandes augmentent le risque de rognage des labels.

✔ Pour les colorbars : utiliser constrained_layout

Cela fonctionne nettement mieux que tight_layout.


📊 Créer des visualisations sans ajuster la mise en page à la main (PyGWalker)

Si vous utilisez Matplotlib surtout pour visualiser des DataFrames, vous n’avez peut‑être plus besoin d’ajuster manuellement les mises en page.

Vous pouvez simplement :

  • Charger votre DataFrame
  • Glisser‑déposer les champs
  • Générer instantanément les graphiques

En utilisant PyGWalker, un outil de visualisation open‑source :

PyGWalker for Data visualization (opens in a new tab)

Voici comment l’utiliser :

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

Ou essayez‑le en ligne :

KaggleGoogle ColabGitHub

Questions fréquentes

  1. Comment éviter les labels coupés avec plt.savefig ? Utilisez bbox_inches='tight', par exemple plt.savefig("plot.png", dpi=300, bbox_inches="tight"). Pour du nouveau code, créez la figure avec layout="constrained".

  2. Que fait bbox_inches="tight" ? Il recalcule la zone sauvegardée pour inclure les labels, titres, légendes et annotations placés hors des axes.

  3. Quand utiliser layout="constrained" plutôt que bbox_inches='tight' ? Utilisez layout="constrained" lors de la création de figures avec subplots, colorbars ou légendes. Utilisez bbox_inches='tight' comme correctif rapide à l’export.

  4. Pourquoi l’image est-elle vide après plt.show() ? Certains backends ferment la figure après plt.show(). Appelez d’abord fig.savefig(...) ou plt.savefig(...), puis plt.show().

  5. Quel DPI utiliser avec savefig ? 150 DPI suffit souvent pour le web et les présentations, 300 DPI pour les rapports et l’impression. Pour une sortie vectorielle, utilisez SVG ou PDF.

Guides liés