W3docs

Graphiques en camembert Matplotlib

Créez et personnalisez des graphiques en camembert avec Matplotlib en Python : couleurs, explosion, graphiques en donut, étiquettes, légendes et enregistrement.

Les graphiques en camembert divisent un cercle en secteurs, où l'angle de chaque secteur est proportionnel à la valeur qu'il représente. Ils fonctionnent mieux lorsque vous disposez d'un petit nombre de catégories (idéalement 2 à 6) et que vous souhaitez montrer comment chaque partie se rapporte à l'ensemble — par exemple, la part de marché par produit ou la répartition budgétaire par département.

Ce chapitre couvre tout, d'un premier graphique minimal jusqu'aux techniques avancées telles que les graphiques en donut, le placement personnalisé des étiquettes et l'enregistrement de figures prêtes pour la publication. Tous les exemples utilisent matplotlib.pyplot, l'API standard de haut niveau.

Installation et configuration

Si vous n'avez pas encore installé Matplotlib, exécutez cette commande dans votre terminal :

pip install matplotlib

Chaque exemple de ce chapitre commence par cet import :

import matplotlib.pyplot as plt

plt est l'alias conventionnel de matplotlib.pyplot. Il vous donne accès à des fonctions comme plt.pie(), plt.title() et plt.show().

Créer un graphique en camembert de base

plt.pie() est la fonction centrale. Au minimum, elle prend une séquence de valeurs numériques — les proportions sont calculées automatiquement pour vous.

import matplotlib.pyplot as plt

labels = ['Desktop', 'Mobile', 'Tablet']
values = [60, 30, 10]

plt.pie(values, labels=labels, autopct='%1.1f%%')
plt.title('Website Visitors by Device')
plt.show()

Paramètres clés utilisés ici :

ParamètreRôle
valuesDonnées numériques ; Matplotlib les convertit en proportions
labelsNoms des catégories affichés à côté de chaque secteur
autopctChaîne de format pour les étiquettes de pourcentage ; '%1.1f%%' donne 60.0%

Le graphique commence à dessiner les secteurs dans le sens antihoraire à partir de la position 3 heures par défaut. La section suivante explique comment modifier cela.

Contrôler la rotation avec startangle

Définir startangle=90 fait pivoter tout le graphique de sorte que le premier secteur commence à la position 12 heures, ce qui est le point de départ le plus naturel pour la plupart des lecteurs.

import matplotlib.pyplot as plt

labels = ['Desktop', 'Mobile', 'Tablet']
values = [60, 30, 10]

plt.pie(
    values,
    labels=labels,
    autopct='%1.1f%%',
    startangle=90,
)
plt.title('Website Visitors by Device')
plt.show()

startangle accepte n'importe quel angle en degrés, mesuré dans le sens antihoraire à partir de l'axe x positif. Une valeur de 90 pointe droit vers le haut.

Personnaliser les couleurs

Passez une liste de codes couleur hexadécimaux ou de noms de couleurs au paramètre colors. La liste doit être au moins aussi longue que vos données.

import matplotlib.pyplot as plt

labels = ['Desktop', 'Mobile', 'Tablet']
values = [60, 30, 10]
colors = ['#ff9999', '#66b3ff', '#99ff99']

plt.pie(
    values,
    labels=labels,
    colors=colors,
    autopct='%1.1f%%',
    startangle=90,
)
plt.title('Website Visitors by Device')
plt.show()

Vous pouvez également utiliser l'une des palettes de couleurs intégrées de Matplotlib. Par exemple, pour extraire trois couleurs de la palette tab10 :

import matplotlib.pyplot as plt
import matplotlib.cm as cm

labels = ['Desktop', 'Mobile', 'Tablet']
values = [60, 30, 10]

cmap = cm.get_cmap('tab10')
colors = [cmap(i) for i in range(len(values))]

plt.pie(values, labels=labels, colors=colors, autopct='%1.1f%%', startangle=90)
plt.title('Website Visitors by Device')
plt.show()

Faire exploser un secteur

Le paramètre explode décale un ou plusieurs secteurs vers l'extérieur pour attirer l'attention sur eux. Il prend un tuple de valeurs flottantes, une par secteur. Une valeur de 0.1 décale un secteur de 10 % du rayon du graphique.

import matplotlib.pyplot as plt

labels = ['Desktop', 'Mobile', 'Tablet']
values = [60, 30, 10]
colors = ['#ff9999', '#66b3ff', '#99ff99']
explode = (0.1, 0, 0)   # offset the first slice (Desktop) only

plt.pie(
    values,
    labels=labels,
    colors=colors,
    explode=explode,
    autopct='%1.1f%%',
    startangle=90,
    shadow=True,          # drop shadow for depth
)
plt.title('Website Visitors by Device')
plt.show()

Définir shadow=True ajoute une légère ombre portée qui met encore davantage en valeur le secteur explosé.

Ajouter un titre et une légende

Utilisez plt.title() pour le titre du graphique et plt.legend() pour une boîte de légende séparée. Une légende est utile lorsque le texte des étiquettes est long ou lorsque les secteurs sont trop petits pour être clairement étiquetés.

import matplotlib.pyplot as plt

labels = ['Desktop', 'Mobile', 'Tablet']
values = [60, 30, 10]
colors = ['#ff9999', '#66b3ff', '#99ff99']

plt.pie(
    values,
    labels=labels,
    colors=colors,
    autopct='%1.1f%%',
    startangle=90,
)
plt.title('Website Visitors by Device')
plt.legend(title='Device type', loc='lower right')
plt.show()

loc accepte des chaînes de position standard telles que 'upper right', 'lower left' et 'center'. Vous pouvez également fournir un tuple bbox_to_anchor pour un positionnement précis au niveau des pixels.

Contrôler la distance des étiquettes

Deux paramètres contrôlent la distance à laquelle les étiquettes se trouvent par rapport au centre du graphique :

  • labeldistance — distance de l'étiquette de catégorie par rapport au centre, exprimée en fraction du rayon. La valeur par défaut est 1.1 (juste à l'extérieur du secteur).
  • pctdistance — distance de l'étiquette de pourcentage autopct par rapport au centre. La valeur par défaut est 0.6 (à l'intérieur du secteur).
import matplotlib.pyplot as plt

labels = ['Desktop', 'Mobile', 'Tablet']
values = [60, 30, 10]

plt.pie(
    values,
    labels=labels,
    autopct='%1.1f%%',
    startangle=90,
    labeldistance=1.2,   # push category labels further out
    pctdistance=0.75,    # move percentages slightly outward from center
)
plt.title('Website Visitors by Device')
plt.show()

Augmentez pctdistance lorsque les secteurs sont grands et que la position par défaut semble encombrée ; diminuez-le lorsque vous avez de nombreux petits secteurs.

Créer un graphique en donut

Un graphique en donut est un graphique en camembert avec un trou au milieu. Utilisez le paramètre wedgeprops pour définir la largeur de l'anneau, exprimée en fraction du rayon. Par exemple, width=0.5 laisse 50 % du rayon comme trou.

import matplotlib.pyplot as plt

labels = ['Desktop', 'Mobile', 'Tablet']
values = [60, 30, 10]
colors = ['#ff9999', '#66b3ff', '#99ff99']

plt.pie(
    values,
    labels=labels,
    colors=colors,
    autopct='%1.1f%%',
    startangle=90,
    pctdistance=0.85,
    wedgeprops=dict(width=0.5),   # ring width = 50 % of radius
)
plt.title('Website Visitors by Device')
plt.show()

Les graphiques en donut sont populaires car le centre vide offre de l'espace pour un total ou une métrique récapitulative, que vous pouvez ajouter avec plt.text(0, 0, 'Total\n100', ha='center', va='center', fontsize=14).

Plusieurs graphiques en camembert côte à côte

Utilisez plt.subplots() pour placer deux graphiques en camembert ou plus sur la même figure. Chaque appel ax.pie() cible son propre objet axes.

import matplotlib.pyplot as plt

fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(10, 5))

# --- Chart 1: this month ---
labels = ['Desktop', 'Mobile', 'Tablet']
values_this_month = [60, 30, 10]
ax1.pie(values_this_month, labels=labels, autopct='%1.1f%%', startangle=90)
ax1.set_title('This Month')

# --- Chart 2: last month ---
values_last_month = [70, 20, 10]
ax2.pie(values_last_month, labels=labels, autopct='%1.1f%%', startangle=90)
ax2.set_title('Last Month')

fig.suptitle('Website Visitors by Device', fontsize=14)
plt.tight_layout()
plt.show()

fig.suptitle() ajoute un titre au-dessus de tous les sous-graphiques. plt.tight_layout() empêche le chevauchement des étiquettes entre les graphiques.

Enregistrer un graphique en camembert dans un fichier

Remplacez plt.show() par plt.savefig() pour écrire le graphique sur le disque plutôt que de l'afficher dans une fenêtre. Cela est indispensable pour les scripts s'exécutant sur des serveurs sans interface graphique ou pour générer des ressources de rapport.

import matplotlib.pyplot as plt

labels = ['Desktop', 'Mobile', 'Tablet']
values = [60, 30, 10]

plt.pie(values, labels=labels, autopct='%1.1f%%', startangle=90)
plt.title('Website Visitors by Device')
plt.savefig('pie_chart.png', dpi=150, bbox_inches='tight')

Options courantes de savefig() :

OptionEffet
dpi=150Résolution en points par pouce (72 à 300 pour un usage courant)
bbox_inches='tight'Supprime les espaces blancs autour de la figure
transparent=TrueEnregistre avec un arrière-plan transparent
format='svg'Écrit un SVG vectoriel au lieu d'un PNG matriciel

Pièges courants

Valeurs qui ne totalisent pas 100. plt.pie() normalise toujours les valeurs de sorte que les secteurs remplissent le cercle complet. Si vos valeurs représentent des pourcentages qui totalisent déjà 100, c'est parfait. Si elles représentent des comptages bruts, c'est également parfait — Matplotlib divise chaque valeur par le total. L'étiquette autopct affiche toujours la proportion, pas la valeur brute.

Valeurs nulles ou négatives. Matplotlib ignore silencieusement les secteurs de valeur nulle (ils ne produisent aucun secteur visible). Les valeurs négatives génèrent une ValueError. Filtrez-les avant d'appeler plt.pie().

Trop de secteurs. Les graphiques en camembert deviennent illisibles avec plus de 6 à 8 secteurs. Pour de nombreuses catégories, envisagez plutôt un graphique en barres. Vous pouvez également regrouper les plus petites catégories dans un secteur « Autre ».

Chevauchement des étiquettes. Lorsque les secteurs sont petits, les étiquettes se chevauchent. Les solutions incluent l'augmentation de labeldistance, l'utilisation d'une légende à la place des étiquettes en ligne (définissez labels=None et appelez plt.legend()), ou l'utilisation d'un graphique en donut offrant plus d'espace à l'extérieur.

Référence rapide

ParamètreTypeDéfautRôle
xsequenceLes valeurs des données
labelslistNoneNoms des catégories
colorslistcycleCouleurs des secteurs
explodetupleNoneDécalage par secteur depuis le centre
autopctstr / callableNoneFormat des étiquettes de pourcentage
pctdistancefloat0.6Distance de l'étiquette de pourcentage depuis le centre
labeldistancefloat1.1Distance de l'étiquette de catégorie depuis le centre
startanglefloat0Angle de départ en degrés
shadowboolFalseOmbre portée
wedgepropsdictNonePropriétés appliquées à chaque secteur (ex. width pour le donut)
counterclockboolTrueSens de dessin des secteurs

Sujets connexes

Was this page helpful?