Grafici a barre con Matplotlib in Python — Guida completa
Crea grafici a barre verticali, orizzontali, raggruppati e in pila in Python con Matplotlib. Include colori, larghezza, barre di errore ed esempi di salvataggio.
Le funzioni bar() e barh() di Matplotlib consentono di creare grafici a barre per confrontare quantità tra categorie diverse. Questo capitolo copre tutto, dal grafico più semplice a serie singola fino ai layout raggruppati e in pila, con opzioni di personalizzazione pratiche utili nei progetti reali: colori, larghezza delle barre, stile dei bordi, barre di errore e salvataggio del risultato su file.
Prima di iniziare, assicurati che Matplotlib sia installato:
pip install matplotlibSe sei nuovo alla libreria, consulta prima i capitoli Introduzione a Matplotlib e Per iniziare.
Cos'è un grafico a barre?
Un grafico a barre utilizza rettangoli la cui lunghezza rappresenta un valore numerico, rendendo semplice il confronto di quantità tra categorie discrete — ad esempio, ricavi mensili, popolazione per paese o punteggi dei test per materia.
Usa un grafico a barre quando:
- Stai confrontando una singola metrica tra categorie (grafico a barre semplice).
- Vuoi mostrare come un totale si suddivide in parti (grafico a barre in pila).
- Devi confrontare più metriche affiancate per le stesse categorie (grafico a barre raggruppato).
- Le etichette delle categorie sono lunghe e si leggono meglio in orizzontale (grafico a barre orizzontale).
Creare un grafico a barre verticale di base
La funzione plt.bar(x, height) riceve una sequenza di etichette di categoria (o posizioni numeriche) e una sequenza corrispondente di altezze delle barre.
import matplotlib.pyplot as plt
categories = ['A', 'B', 'C', 'D', 'E']
values = [10, 24, 36, 40, 15]
plt.bar(categories, values)
plt.title('Sample Bar Chart')
plt.xlabel('Category')
plt.ylabel('Value')
plt.tight_layout()
plt.show()plt.tight_layout() evita che le etichette degli assi vengano tagliate — è una buona abitudine aggiungerla prima di ogni chiamata show() o savefig().
Personalizzare l'aspetto delle barre
Colore
Passa un nome di colore singolo, una stringa esadecimale o una lista di colori per ogni barra al parametro color:
import matplotlib.pyplot as plt
categories = ['A', 'B', 'C', 'D', 'E']
values = [10, 24, 36, 40, 15]
# One color for all bars
plt.bar(categories, values, color='steelblue')
plt.title('Steelblue Bars')
plt.xlabel('Category')
plt.ylabel('Value')
plt.tight_layout()
plt.show()Per colorare ogni barra in modo diverso, passa una lista:
import matplotlib.pyplot as plt
categories = ['A', 'B', 'C', 'D', 'E']
values = [10, 24, 36, 40, 15]
colors = ['#e74c3c', '#3498db', '#2ecc71', '#f39c12', '#9b59b6']
plt.bar(categories, values, color=colors)
plt.title('Multi-Color Bar Chart')
plt.xlabel('Category')
plt.ylabel('Value')
plt.tight_layout()
plt.show()Larghezza delle barre e colore del bordo
Il valore predefinito di width è 0.8 (80% dello spazio tra le posizioni dei tick). Riducilo per un aspetto più leggero o aumentalo per occupare più spazio. edgecolor disegna un contorno intorno a ogni barra:
import matplotlib.pyplot as plt
categories = ['A', 'B', 'C', 'D', 'E']
values = [10, 24, 36, 40, 15]
plt.bar(
categories, values,
width=0.5,
color='cornflowerblue',
edgecolor='navy',
linewidth=1.2,
)
plt.title('Custom Width and Edge')
plt.xlabel('Category')
plt.ylabel('Value')
plt.tight_layout()
plt.show()Aggiungere una legenda
Passa una stringa label a bar() e poi chiama plt.legend():
import matplotlib.pyplot as plt
categories = ['A', 'B', 'C', 'D', 'E']
values = [10, 24, 36, 40, 15]
plt.bar(categories, values, color='teal', label='2024 Sales')
plt.legend()
plt.title('Bar Chart with Legend')
plt.xlabel('Category')
plt.ylabel('Value')
plt.tight_layout()
plt.show()Ruotare le etichette dei tick
I nomi di categoria lunghi si sovrappongono a meno che non vengano ruotati con plt.xticks(rotation=...):
import matplotlib.pyplot as plt
months = ['January', 'February', 'March', 'April', 'May', 'June']
sales = [120, 95, 140, 160, 130, 175]
plt.bar(months, sales, color='darkorange')
plt.xticks(rotation=45, ha='right') # ha='right' aligns the labels nicely
plt.title('Monthly Sales')
plt.xlabel('Month')
plt.ylabel('Units Sold')
plt.tight_layout()
plt.show()Grafici a barre orizzontali
plt.barh(y, width) disegna barre che si estendono orizzontalmente. È particolarmente utile quando le etichette delle categorie sono lunghe, poiché appaiono sull'asse y con molto spazio orizzontale a disposizione.
import matplotlib.pyplot as plt
languages = ['Python', 'JavaScript', 'Java', 'C#', 'TypeScript']
popularity = [30.3, 25.1, 17.8, 12.4, 9.6]
plt.barh(languages, popularity, color='mediumseagreen')
plt.title('Programming Language Popularity (%)')
plt.xlabel('Share (%)')
plt.ylabel('Language')
plt.tight_layout()
plt.show()Suggerimento: ordina i dati prima di tracciare il grafico in modo che la categoria più popolare appaia in cima:
import matplotlib.pyplot as plt
languages = ['Python', 'JavaScript', 'Java', 'C#', 'TypeScript']
popularity = [30.3, 25.1, 17.8, 12.4, 9.6]
# Sort ascending so the highest bar ends up at the top after barh reversal
pairs = sorted(zip(popularity, languages))
popularity_sorted, languages_sorted = zip(*pairs)
plt.barh(languages_sorted, popularity_sorted, color='mediumseagreen')
plt.title('Programming Language Popularity (sorted)')
plt.xlabel('Share (%)')
plt.tight_layout()
plt.show()Grafici a barre raggruppati
Un grafico a barre raggruppato (affiancato) confronta due o più serie per lo stesso insieme di categorie. Matplotlib non dispone di una funzione dedicata — lo si ottiene spostando le posizioni x di ogni serie usando NumPy:
import matplotlib.pyplot as plt
import numpy as np
categories = ['Q1', 'Q2', 'Q3', 'Q4']
sales_2023 = [120, 135, 150, 170]
sales_2024 = [140, 160, 145, 195]
x = np.arange(len(categories)) # [0, 1, 2, 3]
width = 0.35 # width of each individual bar
fig, ax = plt.subplots()
bars1 = ax.bar(x - width / 2, sales_2023, width, label='2023', color='steelblue')
bars2 = ax.bar(x + width / 2, sales_2024, width, label='2024', color='darkorange')
ax.set_title('Quarterly Sales Comparison')
ax.set_xlabel('Quarter')
ax.set_ylabel('Units Sold')
ax.set_xticks(x)
ax.set_xticklabels(categories)
ax.legend()
plt.tight_layout()
plt.show()Punti chiave:
x - width / 2sposta la prima serie a sinistra;x + width / 2sposta la seconda serie a destra, così le barre si trovano affiancate.ax.set_xticks(x)eax.set_xticklabels(categories)posizionano le etichette delle categorie al centro di ogni gruppo.- L'API orientata agli oggetti (
fig, ax = plt.subplots()) è preferita per i grafici raggruppati perché fornisce un controllo esplicito su ogni asse.
Aggiungere etichette di valore sulle barre
Puoi annotare ogni barra con il suo valore usando ax.bar_label() (aggiunto in Matplotlib 3.4):
import matplotlib.pyplot as plt
import numpy as np
categories = ['Q1', 'Q2', 'Q3', 'Q4']
sales_2023 = [120, 135, 150, 170]
sales_2024 = [140, 160, 145, 195]
x = np.arange(len(categories))
width = 0.35
fig, ax = plt.subplots()
bars1 = ax.bar(x - width / 2, sales_2023, width, label='2023', color='steelblue')
bars2 = ax.bar(x + width / 2, sales_2024, width, label='2024', color='darkorange')
ax.bar_label(bars1, padding=3)
ax.bar_label(bars2, padding=3)
ax.set_title('Quarterly Sales with Labels')
ax.set_xlabel('Quarter')
ax.set_ylabel('Units Sold')
ax.set_xticks(x)
ax.set_xticklabels(categories)
ax.legend()
plt.tight_layout()
plt.show()Grafici a barre in pila
Un grafico a barre in pila sovrappone le serie l'una sull'altra, mostrando come le singole parti contribuiscono a un totale. Usa il parametro bottom per indicare a Matplotlib da dove deve partire ogni serie:
import matplotlib.pyplot as plt
import numpy as np
categories = ['A', 'B', 'C', 'D', 'E']
series1 = [10, 24, 36, 40, 15]
series2 = [ 5, 12, 15, 20, 10]
series3 = [ 8, 6, 10, 12, 7]
x = np.arange(len(categories))
plt.bar(x, series1, label='Group 1', color='steelblue')
plt.bar(x, series2, label='Group 2', color='darkorange',
bottom=series1)
plt.bar(x, series3, label='Group 3', color='seagreen',
bottom=np.array(series1) + np.array(series2))
plt.xticks(x, categories)
plt.title('Stacked Bar Chart')
plt.xlabel('Category')
plt.ylabel('Total Value')
plt.legend()
plt.tight_layout()
plt.show()Il bottom della terza serie è la somma elemento per elemento delle prime due, in modo che ogni barra inizi esattamente dove termina la precedente. L'uso di np.array() garantisce che l'addizione funzioni correttamente con le liste.
Barre di errore
Quando i tuoi dati presentano incertezza o variabilità (ad esempio, deviazione standard su misurazioni ripetute), aggiungi le barre di errore con il parametro yerr:
import matplotlib.pyplot as plt
import numpy as np
categories = ['Control', 'Treatment A', 'Treatment B', 'Treatment C']
means = [5.2, 7.8, 6.1, 9.4]
std_devs = [0.5, 0.8, 0.6, 1.1]
plt.bar(
categories, means,
yerr=std_devs,
capsize=5, # width of the error bar caps
color='cornflowerblue',
edgecolor='black',
linewidth=0.8,
)
plt.title('Experimental Results with Error Bars')
plt.xlabel('Group')
plt.ylabel('Mean Value')
plt.tight_layout()
plt.show()capsize controlla le cappette orizzontali in cima e in fondo a ogni barra di errore; un valore tra 4 e 6 è generalmente leggibile.
Salvare un grafico a barre su file
Usa plt.savefig() al posto di plt.show() (o chiamalo prima di show()). Puoi specificare il formato tramite l'estensione del file:
import matplotlib.pyplot as plt
categories = ['A', 'B', 'C', 'D', 'E']
values = [10, 24, 36, 40, 15]
plt.bar(categories, values, color='steelblue')
plt.title('Saved Bar Chart')
plt.xlabel('Category')
plt.ylabel('Value')
plt.tight_layout()
# Save as PNG at 150 dpi
plt.savefig('bar_chart.png', dpi=150)
# Save as vector PDF (ideal for publications)
plt.savefig('bar_chart.pdf')
plt.show()Opzioni di formato comuni: png, pdf, svg, eps. Usa svg o pdf quando hai bisogno di un'immagine scalabile e pronta per la stampa.
Controllare le dimensioni della figura
Per impostazione predefinita Matplotlib crea una figura di 6,4 × 4,8 pollici. Passa figsize=(width, height) a plt.figure() o plt.subplots() per sovrascriverlo:
import matplotlib.pyplot as plt
categories = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun',
'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']
values = [80, 70, 95, 110, 130, 150, 160, 155, 120, 100, 85, 90]
fig, ax = plt.subplots(figsize=(12, 5)) # wider figure for 12 months
ax.bar(categories, values, color='tomato')
ax.set_title('Monthly Data')
ax.set_xlabel('Month')
ax.set_ylabel('Value')
plt.tight_layout()
plt.savefig('monthly_bar_chart.png', dpi=150)
plt.show()Riferimento rapido
| Operazione | Codice |
|---|---|
| Grafico a barre verticale | plt.bar(x, y) |
| Grafico a barre orizzontale | plt.barh(y, width) |
| Cambiare colore | plt.bar(x, y, color='steelblue') |
| Cambiare larghezza | plt.bar(x, y, width=0.5) |
| Barre in pila | plt.bar(x, y2, bottom=y1) |
| Barre di errore | plt.bar(x, y, yerr=errors, capsize=5) |
| Aggiungere etichette di valore | ax.bar_label(bars, padding=3) |
| Ruotare le etichette x | plt.xticks(rotation=45, ha='right') |
| Salvare su file | plt.savefig('file.png', dpi=150) |
Capitoli correlati
- Introduzione a Matplotlib — panoramica della libreria e installazione
- Grafici a linee con Matplotlib — tendenze nei dati continui
- Grafici a dispersione con Matplotlib — relazioni tra due variabili
- Istogrammi con Matplotlib — distribuzione di una singola variabile
- Grafici a torta con Matplotlib — proporzioni parte-tutto
- Etichette Matplotlib — etichette degli assi, titoli e annotazioni
- Griglia Matplotlib — aggiungere e personalizzare le linee della griglia
- Sottografici Matplotlib — più grafici in un'unica figura