W3docs

Grafici a Torta con Matplotlib

Crea e personalizza grafici a torta in Python con Matplotlib: colori, explode, donut, etichette, legende e salvataggio su file.

I grafici a torta dividono un cerchio in fette, dove l'angolo di ciascuna fetta è proporzionale al valore che rappresenta. Funzionano meglio quando si ha un numero ridotto di categorie (idealmente 2–6) e si vuole mostrare come ogni parte si relaziona all'insieme — ad esempio, la quota di mercato per prodotto o la ripartizione del budget per reparto.

Questo capitolo copre tutto, dal primo grafico minimale a tecniche avanzate come i grafici donut, il posizionamento personalizzato delle etichette e il salvataggio di figure pronte per la pubblicazione. Tutti gli esempi utilizzano matplotlib.pyplot, l'API standard di alto livello.

Installazione e Configurazione

Se non hai ancora installato Matplotlib, esegui questo comando nel tuo terminale:

pip install matplotlib

Ogni esempio in questo capitolo inizia con questo import:

import matplotlib.pyplot as plt

plt è l'alias convenzionale per matplotlib.pyplot. Fornisce funzioni come plt.pie(), plt.title() e plt.show().

Creazione di un Grafico a Torta di Base

plt.pie() è la funzione principale. Come minimo accetta una sequenza di valori numerici — le proporzioni vengono calcolate automaticamente.

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

Parametri chiave utilizzati qui:

ParametroScopo
valuesDati numerici; Matplotlib li converte in proporzioni
labelsNomi delle categorie disegnati accanto a ciascuna fetta
autopctStringa di formato per le etichette percentuali; '%1.1f%%' produce 60.0%

Il grafico inizia a disegnare le fette in senso antiorario dalla posizione delle 3 di default. La sezione successiva spiega come modificarlo.

Controllo della Rotazione con startangle

Impostare startangle=90 ruota l'intero grafico in modo che la prima fetta inizi alla posizione delle 12, che è il punto di partenza più naturale per la maggior parte dei lettori.

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 accetta qualsiasi angolo in gradi, misurato in senso antiorario dall'asse x positivo. Un valore di 90 punta direttamente verso l'alto.

Personalizzazione dei Colori

Passa un elenco di codici colore esadecimali o nomi di colori al parametro colors. L'elenco deve essere almeno lungo quanto i tuoi dati.

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

Puoi anche usare qualsiasi colormap integrata in Matplotlib. Ad esempio, per estrarre tre colori dalla 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()

Esplodere una Fetta

Il parametro explode sposta una o più fette verso l'esterno per attirare l'attenzione su di esse. Accetta una tupla di valori float, uno per fetta. Un valore di 0.1 sposta una fetta del 10% del raggio del grafico.

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

Impostare shadow=True aggiunge un'ombra sottile che enfatizza ulteriormente la fetta esplosa.

Aggiunta di un Titolo e di una Legenda

Usa plt.title() per il titolo del grafico e plt.legend() per un riquadro legenda separato. Una legenda è utile quando il testo delle etichette è lungo o quando le fette sono troppo piccole per essere etichettate chiaramente.

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 accetta stringhe di posizione standard come 'upper right', 'lower left' e 'center'. Puoi anche fornire una tupla bbox_to_anchor per un posizionamento preciso a livello di pixel.

Controllo della Distanza delle Etichette

Due parametri controllano quanto lontano si trovano le etichette dal centro del grafico:

  • labeldistance — distanza dell'etichetta di categoria dal centro, come frazione del raggio. Il valore predefinito è 1.1 (appena fuori dalla fetta).
  • pctdistance — distanza dell'etichetta percentuale autopct dal centro. Il valore predefinito è 0.6 (all'interno della fetta).
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()

Aumenta pctdistance quando le fette sono grandi e la posizione predefinita appare disordinata; diminuiscilo quando hai molte fette piccole.

Creazione di un Grafico Donut

Un grafico donut è un grafico a torta con un foro al centro. Usa il parametro wedgeprops per impostare la larghezza dell'anello, espressa come frazione del raggio. Ad esempio, width=0.5 lascia il 50% del raggio come foro.

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

I grafici donut sono popolari perché il centro vuoto fornisce spazio per un conteggio totale o una metrica di sintesi, che puoi aggiungere con plt.text(0, 0, 'Total\n100', ha='center', va='center', fontsize=14).

Più Grafici a Torta Affiancati

Usa plt.subplots() per posizionare due o più grafici a torta sulla stessa figura. Ogni chiamata a ax.pie() si rivolge al proprio oggetto 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() aggiunge un titolo sopra tutti i sottografici. plt.tight_layout() evita la sovrapposizione delle etichette tra i grafici.

Salvataggio di un Grafico a Torta su File

Sostituisci plt.show() con plt.savefig() per scrivere il grafico su disco invece di visualizzarlo in una finestra. Questo è essenziale per gli script in esecuzione su server headless o per generare risorse per report.

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

Opzioni comuni di savefig():

OpzioneEffetto
dpi=150Risoluzione in punti per pollice (72–300 per uso tipico)
bbox_inches='tight'Elimina lo spazio bianco attorno alla figura
transparent=TrueSalva con sfondo trasparente
format='svg'Scrive SVG vettoriale invece di PNG raster

Errori Comuni

Valori che non sommano a 100. plt.pie() normalizza sempre i valori in modo che le fette riempiano il cerchio completo. Se i tuoi valori rappresentano percentuali che già sommano a 100, va bene. Se rappresentano conteggi grezzi, va bene lo stesso — Matplotlib divide ciascun valore per il totale. L'etichetta autopct mostra sempre la proporzione, non il valore grezzo.

Valori zero o negativi. Matplotlib ignora silenziosamente le fette con valore zero (non producono una fetta visibile). I valori negativi generano un ValueError. Filtrali prima di chiamare plt.pie().

Troppe fette. I grafici a torta diventano illeggibili con più di 6–8 fette. Per molte categorie, considera un grafico a barre. In alternativa, raggruppa le categorie più piccole in una fetta "Altro".

Sovrapposizione delle etichette. Quando le fette sono piccole, le etichette si sovrappongono. Le soluzioni includono l'aumento di labeldistance, l'uso di una legenda al posto delle etichette inline (imposta labels=None e chiama plt.legend()), oppure l'utilizzo di un grafico donut con più spazio all'esterno.

Riferimento Rapido

ParametroTipoDefaultScopo
xsequenceI valori dei dati
labelslistNoneNomi delle categorie
colorslistcycleColori delle fette
explodetupleNoneOffset per fetta dal centro
autopctstr / callableNoneFormato per le etichette percentuali
pctdistancefloat0.6Distanza dell'etichetta pct dal centro
labeldistancefloat1.1Distanza dell'etichetta di categoria dal centro
startanglefloat0Angolo iniziale in gradi
shadowboolFalseOmbra
wedgepropsdictNoneProprietà passate a ciascun wedge (es. width per donut)
counterclockboolTrueDirezione in cui vengono disegnate le fette

Argomenti Correlati

Was this page helpful?