W3docs

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 matplotlib

Se 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 / 2 sposta la prima serie a sinistra; x + width / 2 sposta la seconda serie a destra, così le barre si trovano affiancate.
  • ax.set_xticks(x) e ax.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

OperazioneCodice
Grafico a barre verticaleplt.bar(x, y)
Grafico a barre orizzontaleplt.barh(y, width)
Cambiare coloreplt.bar(x, y, color='steelblue')
Cambiare larghezzaplt.bar(x, y, width=0.5)
Barre in pilaplt.bar(x, y2, bottom=y1)
Barre di erroreplt.bar(x, y, yerr=errors, capsize=5)
Aggiungere etichette di valoreax.bar_label(bars, padding=3)
Ruotare le etichette xplt.xticks(rotation=45, ha='right')
Salvare su fileplt.savefig('file.png', dpi=150)

Capitoli correlati

Was this page helpful?