HOWTO · Seaborn
BoxPlot Seaborn
Questo tutorial mostra come creare box plot usando il modulo seaborn in python
In questa pagina
Usa seaborn.boxplot() per riassumere una distribuzione numerica o confrontare valori tra categorie. Indica esplicitamente le colonne dei dati, così Seaborn sa quale variabile associare a ciascun asse. Un box plot mostra la mediana e l’intervallo interquartile (IQR); con la regola predefinita per i baffi, questi raggiungono le osservazioni più estreme entro 1,5 IQR dal box, mentre quelle più lontane appaiono come punti singoli.
Ogni esempio in questo articolo usa le stesse parti: il riquadro copre la metà centrale dei dati, la linea al suo interno è la mediana, i baffi segnano l’intervallo secondo la regola scelta e ogni punto oltre i baffi viene disegnato singolarmente.
Creare un box plot per una distribuzione
Inserisci le misurazioni in una colonna di un DataFrame e associa quella colonna a y. In questo modo il ruolo dei dati è chiaro e il grafico mostra un’etichetta utile sull’asse. L’esempio seguente usa valori fissi, quindi l’input è lo stesso a ogni esecuzione.
import matplotlib.pyplot as plt
import pandas as pd
import seaborn as sns
data = pd.DataFrame({"Score": [12, 14, 15, 16, 18, 19, 21, 24]})
ax = sns.boxplot(data=data, y="Score")
ax.set_title("Score distribution")
plt.show()
La linea all’interno del box indica la mediana. Il box si estende dal primo al terzo quartile, quindi la sua altezza rappresenta la metà centrale delle osservazioni. Un box più alto indica una maggiore dispersione in questa parte centrale dei dati. I baffi mostrano l’intervallo secondo la regola selezionata; non arrivano necessariamente ai valori minimo e massimo.
Confrontare distribuzioni tra categorie
Associa una categoria a x e la misurazione numerica a y per visualizzare un box separato per ogni categoria. In questo insieme di dati, ciascun box riassume il valore di Price per un livello di Quantity. Aggiungendo hue="Product", ogni categoria viene suddivisa in gruppi di prodotti, così è più facile confrontare i prodotti a parità di quantità.
import matplotlib.pyplot as plt
import pandas as pd
import seaborn as sns
data = pd.DataFrame(
{
"Quantity": [5, 6, 7, 8, 5, 6, 7, 8, 5, 6, 7, 8, 5, 6, 7, 8],
"Price": [9, 10, 15, 16, 13, 14, 15, 18, 11, 12, 14, 15, 16, 17, 18, 19],
"Product": ["A", "A", "A", "A", "B", "B", "B", "B"] * 2,
}
)
ax = sns.boxplot(data=data, x="Quantity", y="Price", hue="Product")
ax.set_title("Price by quantity and product")
plt.show()
Usa hue quando il raggruppamento aggiuntivo risponde a una domanda di confronto. Se i gruppi sono numerosi, i box possono sovrapporsi e il grafico diventare affollato; semplifica le categorie oppure crea grafici separati per mantenere leggibili le distribuzioni.
Mostrare le singole osservazioni con uno strip plot
Un box plot sintetizza i dati con statistiche riassuntive. Sovrapponi seaborn.stripplot() quando è utile mostrare anche ogni singola osservazione. Riutilizza gli stessi assi e le stesse associazioni per entrambi i livelli e aggiungi un leggero jitter orizzontale, così i punti con valori simili non si sovrappongono del tutto.
import matplotlib.pyplot as plt
import pandas as pd
import seaborn as sns
data = pd.DataFrame({"Score": [12, 14, 15, 16, 18, 19, 21, 24]})
ax = sns.boxplot(data=data, y="Score", color="lightgray")
sns.stripplot(data=data, y="Score", color="darkred", jitter=0.15, ax=ax)
ax.set_title("Scores with individual observations")
plt.show()
Il box resta il riepilogo, mentre ogni marcatore rappresenta una riga dei dati. Con un insieme di dati più grande, i punti possono sovrapporsi; riduci la dimensione dei marcatori o aumenta la trasparenza per rendere leggibili le zone più dense.
Personalizzare il box plot
Usa i metodi di Matplotlib per impostare i limiti degli assi e concentrarti su un intervallo di valori pertinente, linewidth per modificare lo spessore dei bordi di box e baffi e palette per assegnare colori alle categorie. Il parametro orient controlla l’orientamento: per esempio, orient="h" richiede un grafico orizzontale quando le associazioni tra variabili sono compatibili. I limiti degli assi modificano solo la vista mostrata: sceglili con attenzione e mantieni chiara la scala, per non nascondere osservazioni rilevanti.
import matplotlib.pyplot as plt
import pandas as pd
import seaborn as sns
data = pd.DataFrame(
{
"Quantity": [5, 6, 7, 8, 5, 6, 7, 8, 5, 6, 7, 8, 5, 6, 7, 8],
"Price": [9, 10, 15, 16, 13, 14, 15, 18, 11, 12, 14, 15, 16, 17, 18, 19],
"Product": ["A", "A", "A", "A", "B", "B", "B", "B"] * 2,
}
)
ax = sns.boxplot(
data=data,
x="Quantity",
y="Price",
hue="Product",
linewidth=2.5,
palette="Set2",
)
ax.set_ylim(8, 20)
ax.set_title("Customized price comparison")
plt.show()
I colori della palette corrispondono ai gruppi di hue. Per ottenere box orizzontali, scambia le associazioni della categoria e della misurazione e imposta orient="h"; in tal caso, applica i limiti dell’asse con set_xlim() anziché con set_ylim().
Creare un box plot con catplot()
Usa catplot() con kind="box" per l’interfaccia a livello di figura. Accetta le stesse associazioni esplicite dei dati e può creare pannelli separati con col o row quando vuoi suddividere il confronto in base a un’altra variabile. Per un singolo grafico, seaborn.boxplot() è l’opzione a livello di assi; catplot() è comoda quando la figura deve includere faccette.
import matplotlib.pyplot as plt
import pandas as pd
import seaborn as sns
data = pd.DataFrame(
{
"Quantity": [5, 6, 7, 8, 5, 6, 7, 8, 5, 6, 7, 8, 5, 6, 7, 8],
"Price": [9, 10, 15, 16, 13, 14, 15, 18, 11, 12, 14, 15, 16, 17, 18, 19],
}
)
grid = sns.catplot(data=data, x="Quantity", y="Price", kind="box")
grid.set_axis_labels("Quantity", "Price")
grid.fig.suptitle("Price by quantity")
plt.show()
Poiché catplot() costruisce l’intera figura, restituisce un oggetto griglia invece di un singolo asse; impostate etichette e titoli sulla griglia, come nell’esempio, invece di chiamare ax.set_title().
Gestire un errore di colonna mancante e impostare l’intervallo dei baffi
Poiché ogni mapping nomina una colonna del DataFrame, un nome scritto male fallisce prima che venga disegnato qualsiasi cosa. Questa chiamata chiede una colonna Scroe che i dati non contengono:
import pandas as pd
import seaborn as sns
data = pd.DataFrame({"Score": [12, 14, 15, 16, 18, 19, 21, 24]})
ax = sns.boxplot(data=data, y="Scroe")
La chiamata termina con questo errore:
ValueError: Could not interpret value `Scroe` for `y`. An entry with this name does not appear in `data`.
Correggete il nome in modo che corrisponda esattamente alla colonna — qui, y="Score" — e la stessa chiamata disegnerà il grafico. Quando l’ortografia corretta non è ovvia, stampate data.columns e copiate il nome da lì; il controllo vale allo stesso modo per x, y e hue.
I baffi sono l’altro confine che i lettori incontrano. Aggiungete un valore lontano, 60, ai punteggi: i quartili si spostano appena (primo quartile 15, mediana 18, terzo quartile 21) e con il valore predefinito whis=1.5 il baffo superiore si ferma a 24 mentre 60 viene disegnato come un punto solitario oltre di esso. Passare whis come coppia di percentili allunga i baffi fino a quei percentili dei dati:
import matplotlib.pyplot as plt
import pandas as pd
import seaborn as sns
scores = pd.DataFrame({"Score": [12, 14, 15, 16, 18, 19, 21, 24, 60]})
ax = sns.boxplot(data=scores, y="Score", whis=(0, 100))
plt.show()
Con whis=(0, 100), i baffi raggiungono il minimo 12 e il massimo 60 e nessun punto rimane fuori. Preferite il valore predefinito, a meno che l’intervallo completo non sia il messaggio: baffi allungati nascondono quanto sia insolito il valore estremo. Notate anche che una colonna vuota non solleva un errore — Seaborn restituisce un insieme di assi vuoto — quindi controllate il numero di righe prima di disegnare quando i dati provengono da una pipeline.