Visualizzazione con matplotlib
#
La visualizzazione su Python viene spesso svolta tramite una libreria chiamata matplotlib
, ed in particolare tramite il suo sotto-pacchetto pyplot
. Vediamo qui una semplice introduzione a matplotlib
, che però possiede varie funzionalità. Una documentazione completa può essere trovata come di consueto sul sito ufficiale all’indirizzo: matplotlib.org.
Rappresentare grafici su matplotlib
è estremamente semplice. E’ sufficiente definire due vettori (spesso nella forma di ndarray
, ma è possibile farlo con qualunque tipologia di array), di lunghezza uguale. Le funzioni di libreria andranno quindi a rappresentare i punti le cui coordinate sono descritte dai vettori indicati sul piano bi-dimensionale, che verranno poi connessi con dei segmenti di retta.
Più formalmente, siano \(x = (x_1, \dots, x_N)\) and \(y = (y_1, \dots, y_N)\) due vettori, contenente le coordinate dei dati che vogliamo rappresentare. La funzione plot(x, y)
di matplotlib.pyplot
andrà a rappresentare sul piano cartesiano bidimensionale tutte le coppie \((x_i, y_i)\) per \(i = 1, \dots, N\), e li connetterà con un segmento di retta. Il plot verrà quindi reinderizzato non appena viene chiamato il comando show()
.
import numpy as np
import matplotlib.pyplot as plt
# Creiamo due vettori di esempio
a = 0
b = 2*np.pi
N = 50
x = np.linspace(a, b, N)
y = np.sin(x)
# Visualizzazione
plt.plot(x, y)
plt.show()

Et voilà! Abbiamo disegnato il nostro primo grafico, rappresentante la funzione \(f(x) = sin(x)\).
Avevamo però detto che il grafico sarebbe dovuto essere composto da segmenti di retta, come mai ci appare curvo? In realtà, la curva è un effetto ottico dovuto al numero molto alto di punti rappresentati. Andando a visualizzare meno punti, le linee spezzate appaino chiaramente.
# Rappresentiamo meno punti
N = 8
x = np.linspace(a, b, N)
y = np.sin(x)
# Visualizzazione
plt.plot(x, y)
plt.show()

Di seguito, vedremo come personalizzare il grafico sopra, aggiungento titolo, griglia, nomi degli assi, ecc…
Personalizzare il plot#
Per personalizzare un grafico su matplotlib
, è sufficiente inserire tutte le funzioni atte a specificare i dettagli del grafico, una per ogni riga, comprese tra la funzione che apre il plot (ovvero plt.plot(x, y)
), e la funzione che lo chiude (plt.show()
). Tra le possibili funzioni di personalizzazione, le più comunemente utilizzate sono:
plt.title(str)
: Aggiunge un titolo;plt.xlabel(str)
: Aggiunge una label all’asse x;plt.ylabel(str)
: Aggiunge una label all’asse y;plt.grid()
: Aggiunge la griglia al plot;plt.xlim([a, b])
: Forza il limite di visualizzazione dell’asse x ad essere traa
eb
;plt.ylim([a, b])
: Forza il limite di visualizzazione dell’asse y ad essere traa
eb
;
Per esempio, possiamo personalizzare il grafico sopra in questa maniera:
# Creiamo due vettori di esempio
a = 0
b = 2*np.pi
N = 50
x = np.linspace(a, b, N)
y = np.sin(x)
# Visualizzazione
plt.plot(x, y)
plt.title('Un grafico di f(x) = sin(x)')
plt.xlabel('x')
plt.ylabel('y = sin(x)')
plt.grid()
plt.show()

Plot multipli e personalizzazione della linea#
Chiaramente, è anche possibile rappresentare più curve sullo stesso piano allo stesso tempo. Per farlo, definiamo una nuova coppia di vettori x1
e y1
, e inseriamo semplicemente il comando plt.plot(x1, y1)
tra il comando plt.plot(x, y)
e il plt.show()
.
# Creiamo tre vettori esempio
a = 0
b = 2*np.pi
N = 50
x = np.linspace(a, b, N)
y1 = np.sin(x)
y2 = np.cos(x)
# Visualizzazione
plt.plot(x, y1)
plt.plot(x, y2)
plt.title('Un grafico di funzioni trigonometriche.')
plt.xlabel('x')
plt.ylabel('y')
plt.legend(['f(x) = sin(x)', 'f(x) = cos(x)'])
plt.grid()
plt.show()

Una cosa che si nota, e che richiede un momento di attenzione, è che abbiamo rappresentato, nell’angolo in basso a sinistra del grafico, una legenda. Per farlo, abbiamo inserito il comando plt.legend()
(sempre all’interno del dominio di personalizzazione del plot), passando come input la lista di stringhe da stampare all’interno della legenda, ordinate nello stesso ordine in cui le rispettive funzioni plot
vengono chiamate. matplotlib
si occuperà di gestire i colori e la posizione della legenda in autonomia.
Chiaramente, è anche possibile modificare le specifiche delle linee, ad esempio il colore, lo spessore, e lo stile. I comandi sono i seguenti:
color='str'
: Cambia il colore della linea. Un elenco completo dei colori disponibili si può trovare qui;linewidth=int
: Cambia lo spessore della linea;
Altre specifiche possono essere inserite passando in input alla funzione plt.plot()
una stringa (subito dopo x
e y
), con la seguente notazione:
"o"
: Cambia lo stile della linea a dei punti isolati;"--"
: Cambia lo stile della linea a una linea tratteggiata;"o-"
: Cambia lo stile della linea a una linea continua in cui i punti rappresentati sono segnati con dei cerchi.
Una lista completa delle specifiche si può trovare qui.
# Creiamo due vettori
a = 0
b = 2*np.pi
N = 50
x = np.linspace(a, b, N)
y1 = np.sin(x)
y2 = np.cos(x)
# Visualizziamo
plt.plot(x, y1, 'o', color='red')
plt.plot(x, y2, '--', color='k', linewidth=2)
plt.title('Un grafico di funzioni trigonometriche.')
plt.xlabel('x')
plt.ylabel('y')
plt.legend(['f(x) = sin(x)', 'f(x) = cos(x)'])
plt.grid()
plt.show()

Subplots#
I subplots sono un metodo efficiente di rappresnetare graficamente un’informazione. Questi sono fondamentalmente una matrice di plot, inseriti nella stessa figura, affiancati rispetto alle istruzioni specificate.
Per definire un subplot, si parte definendo una figure
. Questo può essere fatto con la funzione plt.figure(figsize=(w, h))
dove figsize
serve per specificare la dimensione della figura. Dopodiché, per aprire un subplot, si utilizza il comando plt.subplot(nrow, ncol, idx)
, dove nrow
e ncol
rappresentano il numero di righe e di colonne di plots nella matrice di grafici di interesse, mentre idx
è un valore incrementale che, partendo da 1, indica la posizione di ogni specifico plot all’interno del subplot. idx=1
rappresenta il grafico in alto a sinistra e, incrementdando, scorre da sinistra a destra e dall’alto verso il basso.
Ogni volta che si apre un nuovo subplot, è necessario specificare il comando plt.subplot(nrow, ncol, idx)
, con lo stesso valore di nrow
e ncol
, ma valore incrementale di idx
.
# Creiamo dei dati
N = 200
x1 = np.random.normal(0, 1, (N, ))
y1 = np.random.normal(0, 1, (N, ))
x2 = np.random.normal(0, 0.5, (N, ))
y2 = np.random.normal(0, 2, (N, ))
# Visualizziamo
plt.figure(figsize=(10, 4))
plt.subplot(1, 2, 1)
plt.plot(x1, y1, 'o', color='red')
plt.title('Distribuzione normale')
plt.xlabel('x')
plt.ylabel('y')
plt.xlim([-3, 3])
plt.ylim([-4, 4])
plt.grid()
plt.subplot(1, 2, 2)
plt.plot(x2, y2, 'o', color='k')
plt.title('Distribuzione normale di dati verticali')
plt.xlabel('x')
plt.ylabel('y')
plt.xlim([-3, 3])
plt.ylim([-4, 4])
plt.grid()
plt.show()
