Introduzione
Quando un dataset contiene molte informazioni, un singolo grafico può non essere sufficiente. In questi casi è utile costruire una piccola dashboard composta da più visualizzazioni coordinate. Matplotlib permette di organizzare diversi grafici nella stessa figura usando i subplot e il layout avanzato GridSpec.
Questo approccio è particolarmente utile per analizzare, ad esempio, le prestazioni di un negozio online. Possiamo mostrare contemporaneamente:
- la distribuzione degli ordini per categoria;
- il confronto tra ricavi e numero di prodotti venduti;
- la relazione tra sconto applicato e valore dell´ordine;
- la distribuzione dei tempi di consegna.
La visualizzazione multipannello consente di confrontare prospettive diverse senza aprire numerose finestre separate. Un buon layout deve però essere leggibile: ogni pannello deve avere un titolo chiaro, assi comprensibili e una dimensione adeguata.
Codice completo
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.gridspec import GridSpec
# Generatore casuale con risultato riproducibile
rng = np.random.default_rng(42)
# Dati simulati relativi a 180 ordini
categorie = np.array(["Elettronica", "Casa", "Libri", "Sport"])
categoria_ordini = rng.choice(categorie, size=180)
prezzi = rng.uniform(15, 250, size=180)
quantita = rng.integers(1, 5, size=180)
sconti = rng.uniform(0, 35, size=180)
# Il ricavo dipende dal prezzo, dalla quantità e dallo sconto
ricavi = prezzi * quantita * (1 - sconti / 100)
# Tempi di consegna simulati in giorni
tempi_consegna = np.maximum(
rng.normal(loc=4.5, scale=1.7, size=180),
1
)
# Creiamo una figura con una griglia di 2 righe e 2 colonne
fig = plt.figure(figsize=(13, 8), constrained_layout=True)
griglia = GridSpec(2, 2, figure=fig)
# Pannello 1: ricavi medi per categoria
ax1 = fig.add_subplot(griglia[0, 0])
ricavi_medi = [
ricavi[categoria_ordini == categoria].mean()
for categoria in categorie
]
colori = ["#4575b4", "#74add1", "#fdae61", "#d73027"]
ax1.bar(categorie, ricavi_medi, color=colori)
ax1.set_title("Ricavo medio per categoria")
ax1.set_ylabel("Ricavo medio (€)")
ax1.tick_params(axis="x", rotation=20)
ax1.grid(axis="y", alpha=0.3)
# Pannello 2: relazione tra sconto e ricavo
ax2 = fig.add_subplot(griglia[0, 1])
punti = ax2.scatter(
sconti,
ricavi,
c=quantita,
cmap="viridis",
alpha=0.7,
edgecolors="white",
linewidths=0.5
)
ax2.set_title("Sconto e valore dell´ordine")
ax2.set_xlabel("Sconto (%)")
ax2.set_ylabel("Ricavo (€)")
ax2.grid(alpha=0.25)
# La barra dei colori spiega il significato del colore dei punti
barra_colori = fig.colorbar(punti, ax=ax2)
barra_colori.set_label("Quantità acquistata")
# Pannello 3: numero di ordini per categoria
ax3 = fig.add_subplot(griglia[1, 0])
conteggi = [
np.sum(categoria_ordini == categoria)
for categoria in categorie
]
ax3.barh(categorie, conteggi, color="#66c2a5")
ax3.set_title("Numero di ordini")
ax3.set_xlabel("Ordini")
ax3.grid(axis="x", alpha=0.3)
# Scriviamo il valore direttamente accanto a ogni barra
for indice, valore in enumerate(conteggi):
ax3.text(valore + 1, indice, str(valore), va="center")
# Pannello 4: distribuzione dei tempi di consegna
ax4 = fig.add_subplot(griglia[1, 1])
ax4.boxplot(
tempi_consegna,
vert=False,
patch_artist=True,
boxprops={"facecolor": "#fdae61"},
medianprops={"color": "black", "linewidth": 2}
)
ax4.set_title("Distribuzione dei tempi di consegna")
ax4.set_xlabel("Giorni")
ax4.set_yticks([])
ax4.grid(axis="x", alpha=0.3)
# Titolo generale della dashboard
fig.suptitle(
"Dashboard riepilogativa degli ordini",
fontsize=18,
fontweight="bold"
)
# Salvataggio ad alta risoluzione
fig.savefig(
"dashboard_ordini.png",
dpi=150,
bbox_inches="tight"
)
plt.show()
Spiegazione
Costruire la griglia
GridSpec permette di descrivere la disposizione dei pannelli come una griglia. Nell´esempio, GridSpec(2, 2) crea due righe e due colonne. Ogni grafico viene inserito in una posizione specifica tramite espressioni come griglia[0, 0] o griglia[1, 1].
La funzione fig.add_subplot() collega un asse alla figura principale. Ogni oggetto restituito, come ax1 o ax2, rappresenta un pannello indipendente sul quale è possibile disegnare e impostare titoli, etichette e griglie.
Perché usare GridSpec invece di una semplice griglia
Per layout regolari si può usare anche plt.subplots(2, 2). GridSpec è però più flessibile: consente di far occupare a un pannello più righe o più colonne. Per esempio, un asse può essere creato con fig.add_subplot(griglia[:, 0]), occupando tutta la prima colonna.
Questa flessibilità è utile quando un grafico principale deve essere più grande dei grafici di supporto. Una dashboard reale potrebbe avere un grafico di sintesi largo quanto l´intera finestra e due grafici più piccoli sotto di esso.
Usare colori e annotazioni
Nel secondo pannello, il colore dei punti rappresenta la quantità acquistata. La funzione fig.colorbar() aggiunge una legenda cromatica, indispensabile quando il colore contiene informazione.
Nel grafico a barre orizzontali i valori vengono scritti accanto alle barre con ax3.text(). Questa tecnica evita che il lettore debba stimare il valore osservando soltanto la scala dell´asse.
Gestire lo spazio
L´argomento constrained_layout=True aiuta Matplotlib a evitare sovrapposizioni tra titoli, etichette e barra dei colori. È una soluzione moderna e spesso preferibile a chiamare manualmente plt.tight_layout().
Best practice
- Definisci una domanda per ogni pannello: ogni grafico dovrebbe rispondere a un quesito concreto, non essere inserito soltanto per riempire lo spazio.
- Usa titoli descrittivi: “Ricavo medio per categoria” è più utile di un titolo generico come “Grafico 1”.
- Mantieni una gerarchia visiva: il titolo generale deve essere più evidente dei titoli dei singoli pannelli.
- Evita troppe palette diverse: colori coerenti rendono la dashboard più professionale e leggibile.
- Non duplicare le legende: se una stessa codifica cromatica è condivisa, valuta l´uso di una sola legenda comune.
- Controlla le dimensioni: una figura troppo piccola rende il testo illeggibile, soprattutto quando contiene quattro o più pannelli.
- Salva con una risoluzione adeguata: per report e presentazioni,
dpi=150odpi=300produce immagini più nitide. - Considera l´accessibilità: non affidarti soltanto al colore; aggiungi etichette, forme o annotazioni per comunicare i dati.
Riepilogo
Una dashboard composta da più subplot permette di osservare lo stesso fenomeno da punti di vista differenti. Con GridSpec possiamo controllare con precisione la disposizione degli assi e creare layout più flessibili rispetto a una semplice griglia uniforme.
Le idee principali sono:
- creare una figura principale con
plt.figure(); - definire la struttura con
GridSpec; - aggiungere ogni pannello tramite
fig.add_subplot(); - personalizzare ogni asse indipendentemente;
- usare
constrained_layoutesavefig()per ottenere un risultato ordinato e riutilizzabile.
