Visualizzazione dati 1

Scarica zip esercizi

Naviga file online

Introduzione

Excel ci permette di creare molti tipi di visualizzazione per i nostri dati ma è molto più limitato rispetto a Python ed il risultato solitamente è di qualità inferiore. In questo tutorial in particolare guarderemo:

Grafici Matplotlib

  • grafici a punti e a linee

  • posizionare grafici

  • mettere oggetti e scritte in sovraimpressione

  • istogrammi, grafici a torte e barre

Infografiche SVG (cenni)

Incorporare codice HTML in Jupyter

  • calendari

  • video

  • mappe

Jupyter è molto flessibile, e permette di fare grafici interattivi, mettere insieme collezioni di notebook per creare dei veri e propri libri in formato pdf, così come creare siti web. Qua di seguito mettiamo dei cenni - in future versioni del tutorial le tratteremo più in dettaglio.

Che fare

  • scompatta lo zip in una cartella, dovresti ottenere qualcosa del genere:

visualization
    visualization1.ipynb
    visualization1-sol.ipynb
    visualization2-chal.ipynb
    jupman.py

ATTENZIONE: Per essere visualizzato correttamente, il file del notebook DEVE essere nella cartella szippata.

  • apri il Jupyter Notebook da quella cartella. Due cose dovrebbero aprirsi, prima una console e poi un browser. Il browser dovrebbe mostrare una lista di file: naviga la lista e apri il notebook visualization1.ipynb

  • Prosegui leggendo il file degli esercizi, ogni tanto al suo interno troverai delle scritte ESERCIZIO, che ti chiederanno di scrivere dei comandi Python nelle celle successive.

Scorciatoie da tastiera:

  • Per eseguire il codice Python dentro una cella di Jupyter, premi Control+Invio

  • Per eseguire il codice Python dentro una cella di Jupyter E selezionare la cella seguente, premi Shift+Invio

  • Per eseguire il codice Python dentro una cella di Jupyter E creare una nuova cella subito dopo, premi Alt+Invio

  • Se per caso il Notebook sembra inchiodato, prova a selezionare Kernel -> Restart

1. Matplotlib e Numpy

Matplotlib è una libreria molto famosa per disegnare grafici in Python; è alla base di molti framework per la visualizzazione dei dati e quindi è importante capire il suo funzionamento.

Installazione

Per prima cosa bisogna installare la libreria usando da console:

Windows / Anaconda: Con Anaconda, in teoria già hai Matplotlib! Prova ad eseguire il codice che trovate nel primo esempio qua sotto e vedi se viene mostrato qualcosa in Jupyter. Dovessero esserci problemi, si può sempre tentare di eseguire questo codice nell’Anaconda Prompt:

conda install matplotlib -c conda-forge

Ubuntu: eseguire nel terminale

sudo apt-get install python3-matplotlib

Mac / Linux generico: eseguire nel terminale

python3 -m pip install --user matplotlib

Nota Se vedi errori riguardo permessi non sufficienti, potrebbe essere necessario lanciare il comando come amministratore. se questo accade, prova ad installare a livello di sistema con il comando:

sudo python3 -m pip install matplotlib

Primo esempio

A sua volta Matplotlib utilizza una libreria matematica chiamata Numpy: questa libreria viene automaticamente installata quando installiamo Matplotlib e quindi non dobbiamo servirà installarla manualmente. Queste due librerie sono molto potenti e estensive, tanto da poter coprire un corso intero per ognuna di queste: il nostro obbiettivo però è quello di imparare le funzioni più importanti e capire il funzionamento in generale, per la documentazione completa è possibile accedere alla lista delle funzioni disponibili sui rispettivi siti internet.

Vediamo un primo esempio:

NOTA: La prima volta che esegui la cella qua sotto potrebbe sembrare tutto bloccato!

Potresti anche vedere comparire un messaggio come questo: UserWarning: Matplotlib is building the font cache using fc-list. This may take a moment. Matplotlib is building the font cache using fc-list.

Niente paura, non è un errore ma solo un avvertimento (la linea inizia dicendo UserWarning non UserError): il rallentamento è causato soltanto dal fatto che Matplotlib vuole sapere quali font (tipi di carattere) può utilizzare per disegnare i grafici. È sufficiente aspettare qualche minuto e il processo riprenderà in maniera automatica appena la libreria completerà la ricerca.

[1]:
%matplotlib inline
import matplotlib
import matplotlib.pyplot as plt
import numpy as np

x = np.arange(0, 11, 1.)
y = 2*x + 10

plt.plot(x, y, 'bo')
plt.title('Performance Attesa Esame Fisica')
plt.xlabel('Esercizi svolti')
plt.ylabel('Votazione esame')

plt.show()

../_images/visualization_visualization1-sol_4_0.png

Il codice qui sopra serve per disegnare il risultato atteso dei voti in relazione al numero di esercizi svolti. Vediamo la prima riga:

%matplotlib inline

Perché inizia con un %? La prima riga in realtà non è una istruzione Python ma è una istruzione per l’integrazione tra Jupyter e Matplotlib, e serve per comunicare a queste due librerie in che modo vogliamo visualizzare i grafici generati da Matplotlib. In questo caso inline significa che vogliamo vedere i grafici all’interno del notebook appena eseguiamo la cella che li disegna.

Guardiamo le linee successive:

import matplotlib
import matplotlib.pyplot as plt
import numpy as np

Queste importano matplotlib, matplotlib.pyplot e numpy; per le ultime due useremo per brevità degli alias plt e np, che sono dei nomi alternativi che assegnamo noi al momento, per riferirci in modo rapido alle librerie nel codice che segue.

Una volta importate le librerie prepariamo i valori che vogliamo visualizzare. Supponiamo di avere una formula lineare che collega il numero di esercizi svolti con il risultato dell’esame, per esempio possiamo usare questa funzione:

\[y=2x+10\]

Per tradurla in Python usando la libreria Numpy, possiamo fare così:

x = np.arange(0, 11, 1.)
y = 2*x + 10

Per visualizzare la retta sul grafico è necessario mettere dei valori per la x in un vettore di Numpy. A tal fine, per eseguire questo campionamento scegliendo dei valori di \(x\), abbiamo usato la funzione arange di numpy: i parametri sono simili alla funzione già fornita da Python range (che restituisce una serie di numeri selezionando un intervallo e opzionalmente un incremento) ma in questo caso arange restituisce un oggetto di tipo numpy.ndarray che permette di essere utilizzato all’interno di espressioni (al contrario di tuple o list che sono meno flessibili).

Guardiamo meglio la prima riga:

x = np.arange(0, 11, 1.)
  • Il primo parametro 0 rappresenta il limite inferiore (compreso nella serie)

  • il secondo 11 il limite superiore (escluso dalla serie)

  • mentre il terzo 1. rappresenta l’incremento tra un numero e quello successivo nella serie generata.

✪ ESERCIZIO 1.1: Prova a usare il comando type per controllare quale è il tipo di valore ritornato dalla chiamata a np.arange

Mostra soluzione
[2]:
# scrivi qui il comando type


[2]:
numpy.ndarray

Dopo aver generato i valori di x e y in due vettori possiamo disegnare un grafico. Il grafico più semplice che si possa plottare è un grafico con dei punti nel piano e la funzione da chiamare per farlo è plt.plot():

plt.plot(x, y, 'bo')

Questa funzione può ricevere come parametro due liste di oggetti aventi la stessa dimensione rappresentando posizionalmente le coordinate dei punti mentre il terzo parametro (opzionale), serve per indicare lo stile dell’oggetto da disegnare: nel nostro caso "bo" significa colore blue e la o dice a Python di stampare cerchi (per maggiori informazioni scrivi help(plt.plot)).

Ora l’oggetto plt contiene le informazioni riguardanti il grafico che vogliamo vedere, ma mancano ancora alcune informazioni come il titolo e le etichette sugli assi. Per settare questi valori utilizziamo i metodi plt.title() (per il titolo), plt.xlabel() (per l’etichetta dell’asse x) e plt.ylabel() (per l’etichetta dell’asse y):

plt.title('Performance Attesa Esame Fisica')
plt.xlabel('Esercizi svolti')
plt.ylabel('Votazione esame')

L’ultima istruzione:

plt.show()

è il metodo che veramente genera il grafico e pulisce l’oggetto plt per renderlo pronto a disegnare un nuovo grafico. Per il momento, consideriamo che dopo che aver chiamato questo metodo non sarà più possibile apportare modifiche al grafico quindi lo chiameremo per ultimo.

✪ ESERCIZIO 1.2: Riscrivi a mano qua sotto il codice visto sopra, e prova ad eseguirlo con Ctrl+Invio:

Mostra soluzione
[3]:
# scrivi qui il codice


../_images/visualization_visualization1-sol_15_0.png

✪ ESERCIZIO 1.3: Copia e incolla qua sotto l’esempio precendente, questa volta cambiando il colore della linea (usa r per il rosso) e lo stile della linea, usando una linea continua con il carattere -.

Mostra soluzione
[4]:
# scrivi qui il codice


../_images/visualization_visualization1-sol_20_0.png

✪ ESERCIZIO 1.4: Ricopia con il copia e incolla il codice qua sotto, e prova ad aggiungere la griglia con il comando plt.grid(), ricordandoti che puoi sempre usare lo help con help(plt.grid) (nota: quando chiedi lo help non devi mettere le parentesi tonde () dopo il nome del metodo grid !)

Mostra soluzione
[5]:
# scrivi qui il codice


../_images/visualization_visualization1-sol_25_0.png

✪ ESERCIZIO 1.5: Copia e incolla il codice dell’esempio precedente qua sotto, e prova ad aggiungere l’istruzione:

plt.annotate(
    "Risultato minimo\nper la sufficienza",
    xy=(4, 18), arrowprops={'arrowstyle':'->'}, xytext=(6, 17.2))

Che cosa succede? Che cosa fanno i parametri? Prova a variare i parametri cercando nella guida di matplotlib

Mostra soluzione
[6]:
# scrivi qui il codice


../_images/visualization_visualization1-sol_30_0.png

Le etichette sugli assi

Puoi anche cambiare le etichette (ticks) in prossimità delle barrette sugli assi usando le funzioni plt.xticks e plt.yticks:

Nota: invece di xticks potresti usare direttamente variabili categoriche SE hai installato matplotlib >= 2.1.0

Qua usiamo gli xticks perchè a volte devi direttamente manipolarli comunque.

[7]:
%matplotlib inline
import matplotlib.pyplot as plt

xs = [1, 2, 3, 4, 5, 6]
ys = [2, 4, 6, 8,10,12]

plt.plot(xs, ys, 'ro')

plt.title("La mia funzione")
plt.xlabel('x')
plt.ylabel('y')

# PRIMA NECESSITA UNA SEQUENZA CON LE POSIZIONI,
# POI UNA SEQUENZA DELLA STESSA LUNGHEZZA CON LE ETICHETTE

plt.xticks(xs, ['a', 'b', 'c', 'd', 'e', 'f'])
plt.show()
../_images/visualization_visualization1-sol_32_0.png

2. Stile MATLAB vs. Object-Oriented

Finora abbiamo usato un sistema per la creazione di grafici chiamato pyplot (spesso chiamato solo plt nel codice). Questo sistema è di proposito molto simile a quello presente in altri software molto usati come MATLAB o GNUplot, che però non sono stati originariamente scritti in Python.

Matplotlib permette anche di disegnare grafici utilizzando un paradigma più proprio di Python, e quindi più flessibile e consigliato.

Purtroppo è importante saper leggere entrambe le notazioni in quanto sono entrambe molto utilizzate.

Come prima cosa è importante conoscere i nomi degli elementi all’interno dei grafici per poter capire meglio queste differenze, esistono 4 elementi principali:

  • Figure sono la figura completa, cioè l’immagine composta da uno (o più grafici); questo è l’unico elemento a poter essere disegnato.

  • Axes sono i grafici all’interno di una figura, questi contengono la rappresentazione dei grafici che ci interessa,

  • Axis sono le assi di un sistema cartesiano, ogni oggetto di tipo Axes ne contiene 2 o 3 e ne compongono il sistema di riferimento.

  • Artist tutto quello che viene disegnato nell’immagine (Figure, Axes, Axis).

Anatomy-98343

Nell’esempio qui sotto viene riportata lo stesso grafico dell’esempio 1 usando il metodo object-oriented:

[8]:
%matplotlib inline
import matplotlib
import matplotlib.pyplot as plt
import numpy as np

x = np.arange(0, 11, 1.)
y = 2*x + 10

fig = plt.figure(figsize=(10,2))  # larghezza 10 pollici, altezza 2 pollici
ax = fig.add_subplot(111)
ax.plot(x, y, 'o')
ax.set_title('Performance attesa Esame Fisica')
ax.set_xlabel('Esercizi svolti')
ax.set_ylabel('Votazione esame')
plt.tight_layout()
plt.show()
../_images/visualization_visualization1-sol_34_0.png

Guardiamo la prima (linea 1):

fig = plt.figure()

utilizzo plt.figure() per creare recuperare una Figure dal modulo pyplot,

Poi in linea 2:

ax = fig.add_subplot(111)

genero gli Axes, cioè il grafico vero e proprio usando il metodo fig.add_subplot(). Questo metodo prende in ingresso un numero di 3 cifre, ognuna di queste ha un significato particolare:

  • La prima cifra rappresenta il numero di righe in cui dividere la figura

  • La seconda cifra rappresenta il numero di colonne in cui dividere la figura

  • La terza cifra è la cella corrispondente nella griglia generata con le prime due cifre.

Restituisce un Axes all’interno della figura, la cui cella è enumerata partendo da 1, da sinistra verso destra, dall’alto verso il basso.

In questo caso 111 significa che l’Axes ritornato sarà allineato ad una griglia di 1 riga, 1 colonna, ed occuperà il posto del #1 grafico.

Il metodo successivo disegna il grafico nell’Axes selezionato (linea 3).

I comandi successivi sono analoghi a quelli negli esempi precedenti:

ax.plot(x, y, 'o')
ax.set_title('Performance attesa Esame Fisica')
ax.set_xlabel('Esercizi svolti')
ax.set_ylabel('Votazione esame')

, ma fai attenzione al nome e all’oggetto sul quale sono chiamati: adesso abbiamo il metodo ax.set_title() invece di plt.title() per settare il titolo, ax.set_xlabel() invece di plt.xlabel() per settare l’etichetta del’asse delle asciesse e ax.set_ylabel() invece di plt.ylabel() per settare l’etichetta del’asse delle ordinate.

L’istruzione plt.tight_layout():

plt.tight_layout()
plt.show()

infine fa spazio tra i grafici per ottimizzarlo in maniera che non si sormontino tra loro: funziona in maniera automatica e fa tutto il possibile perché questo non accada ma non può fare i miracoli: alcuni layout potrebbero comunque soffrire di qualche sovrapposizione se lo spazio disponibile è davvero limitato.

✪ ESERCIZIO 2.1: Come al solito, inizia a copiare manualmente qua sotto il codice dell’esempio precedente, ed eseguilo con Control+Invio:

Mostra soluzione
[9]:
# scrivi qui


../_images/visualization_visualization1-sol_39_0.png

Proviamo adesso a mettere due grafici, uno di fianco all’altro. in maniera che ci siano due grafici per gli stessi dati, ma su due righe: nel grafico superiore ci sarà una linea rossa e in quello inferiore i punti saranno blu. Per realizzare questo effetto, dovrai aggiungere dei subplot alla figura. Prova a giocare un po’ con i codici per i quadranti di subplot per vedere cosa succede.

[10]:
%matplotlib inline
import matplotlib
import matplotlib.pyplot as plt
import numpy as np

x = np.arange(0, 11, 1.)
y = 2*x + 10

fig = plt.figure()
ax = fig.add_subplot(121)  # griglia a 1 riga, 2 colonne, grafico numero 1
ax.plot(x, y, 'bo')
ax.set_title('GRAFICO A SINISTRA')
ax.set_xlabel('Esercizi svolti')
ax.set_ylabel('Votazione esame')

ax = fig.add_subplot(122)  # griglia a 1 riga, 2 colonne, grafico numero 2
ax.plot(x, -y, 'bo')  # notate che mettendo meno davanti a y tutti i valori nell'ndarray diventano negativi
ax.set_title('GRAFICO A DESTRA')
ax.set_xlabel('Esercizi svolti')
ax.set_ylabel('Votazione esame')

plt.tight_layout()
plt.show()
../_images/visualization_visualization1-sol_41_0.png

✪✪ ESERCIZIO 2.2: Adesso prova a copiare il grafico (anche di/con copia incolla) in maniera che ci siano due grafici per gli stessi dati, ma su due righe: nel grafico superiore ci sarà una linea rossa e in quello inferiore i punti saranno blu. Per realizzare questo effetto, dovrai aggiungere dei subplot alla figura. Prova a giocare un po’ con i codici per i quadranti di subplot per vedere cosa succede.

Mostra soluzione
[11]:
# scrivi qui


../_images/visualization_visualization1-sol_46_0.png

✪✪ ESERCIZIO 2.3: Prova a fare 6 grafici su 3 righe e 2 colonne

Mostra soluzione
[12]:
# scrivi qui


../_images/visualization_visualization1-sol_51_0.png

3. Altri tipi di grafici

Oltre a questo tipo di grafico Matplotlib permette ulteriori tipi di grafici come grafici a barre, istogrammi, piechart, scatter, polari, etc. Nella documentazione è possibile trovare la spiegazione dettagliata di tutti i tipi di grafico, nei prossimi esempi ne sono riportati alcuni.

Grafici a barre

Possiamo creare un grafico a barre usando il comando plt.bar.

[13]:
import numpy as np
import matplotlib.pyplot as plt

xs = [1,2,3,4]
ys = [7,5,8,2]

plt.bar(xs, ys,
        0.5,             # la larghezza delle barre
        color='green',   # qualcuno ha suggerito che il colore di default blu è deprimente,
                         # perciò mettiamo il verde
        align='center')  # alline le barre sull'xtick

plt.show()
../_images/visualization_visualization1-sol_54_0.png

Distribuzioni

Proviamo a generare una distribuzione di numeri da usare in seguito. Per cominciare, generiamo dei valori secondo una distribuzione gaussiana e mettiamoli nell’ndarray che chiamiamo segnale. Questi valori ci serviranno per esperimenti in seguito. Per questi esempi, useremo un nuovo modo per ottenere le variabili fig e ax con il metodo subplots:

[14]:
plt.subplots()
[14]:
(<Figure size 432x288 with 1 Axes>, <AxesSubplot:>)
../_images/visualization_visualization1-sol_56_1.png

Se vedi plt.subplots ci ritorna due valori come una tupla ( e ci mostra anche il grafico per ora vuoto in Jupyter). Il primo valore è la Figure e il secondo è un Axes. Per metterli rapidamente in variabili con nomi che piacciono a noi come fig e ax, possiamo usare questa notazione:

[15]:
fig, ax = plt.subplots()
../_images/visualization_visualization1-sol_58_0.png

Proviamo adesso a generare un ndarray di numeri casuali, distribuiti secondo una distribuzione gaussiana. Definiamo la media mu, lo scarto quadratico medio sigma. La funzione np.random.normal() richiede come parametro la media, l’SQM e il numero di esempi che devono essere estratti, in questo caso 500:

[16]:

mu = 0 # media sigma = 1 # sqm num_bins = 50 # numero di colonne per l'istogramma # impostiamo il generatore di numeri casuali di numpy per ottenere # sempre la stessa sequenza di numeri pseudocasuali np.random.seed(0) segnale = np.random.normal(mu, sigma, 500) # generiamo 500 valori distribuiti come una gaussiana, e mettiamoli nell'ndarray 'x' fig, ax = plt.subplots() # subplots restituisce una tupla con figura e asse ax.plot(segnale) plt.show()
../_images/visualization_visualization1-sol_60_0.png

Come atteso, i numeri sono centrati sulla linea corrispondente a 0.

Istogrammi delle frequenze

In precedenza abbiamo esplicitamente creato dei grafici a barre, ma matplotlib mette a disposizione la funzione ax.hist per gestire automaticamente istogrammi.

Proviamo per esempio a produrre un istogramma che mostri in percentuale quanti numeri generati nel paragrafo precedente sono stati pari a -2, quanti pari a -1, 0, 1 , 2 , etc..

[17]:
import matplotlib.pyplot as plt
import numpy as np

fig, ax = plt.subplots()  # creiamo Figure and Axes in un comando solo

# generiamo il segnale secondo distribuzione gaussiana

mu = 0  # media
sigma = 1  # sqm

# impostiamo il generatore di numeri casuali di numpy per ottenere
# sempre la stessa sequenza di numeri pseudocasuali
np.random.seed(0)

# generiamo 500 valori distribuiti come una gaussiana, e mettiamoli nell'ndarray 'x'
segnale = np.random.normal(mu, sigma, 500)

# aggiungiamo l'istogramma
num_bins = 50    # numero di colonne per l'istogramma
# in questo caso hist ritorna tre valori che mettiamo in altrettante variabili
n, bins, columns = ax.hist(segnale, num_bins)

ax.set_xlabel('Segnale')
ax.set_ylabel('Numero di elementi')
ax.set_title(r'Istogramma di una Gaussiana con $\mu=0$, $\sigma=1$')
fig.tight_layout()
plt.show()
../_images/visualization_visualization1-sol_64_0.png

Nella parte per l’istogramma, chiamiamo il metodo ax.hist(): questo prende come parametri l’array contenente i dati che abbiamo generato (segnale), e il numero di partizioni dell’istogramma. Oltre a disegnare la funzione di probabilità dentro l’Axes ax restituisce anche i valori numerici per ogni colonna in n, i valori per usati per partizionare i dati nelle varie colonne in bins e le colonne vere e proprie, intesi come i “rettangoli colorati” che compongono il grafico, in columns.

I comandi successivi li conosciamo già, ma facciamo attenzione al set_title questa volta: come puoi vedere ci sono dei caratteri $ all interno del titolo: se hai mai usato o conosci Latex avrai sicuramente riconosciuto la notazione, infatti Matplotlib permette di inserire testo Latex all’interno dei grafici generati; per chi non lo conoscesse Latex è un linguaggio di markup che viene utilizzato per scrivere documenti di testo, molto utilizzato in ambito scientifico anche grazie alla potenza e semplicità nell’esprimere formule matematiche. Dal momento che molti comandi Latex iniziano con la slash \, se la usassimo direttamente senza accorgimenti Python la interpreterebbe come inizio di una sequenza di _escape (come per esempio \n): per evitare questo problema abbiamo messo la lettera r all’inizio della stringa per creare cosiddetta raw string, cioè una stringa dove le sequenze di escape non vengono interpretate.

✪ ESERCIZIO 3.1: Copia sotto il codice per plottare l’istogramma di qua sopra, ma invece di generare il segnale con distribuzione gaussiana, prova invece a settarlo uguale a liste come queste. Che grafici prevedi ? Dove saranno allineati lungo l’asse y ?

  • [1,1,1,1,1, 2,2, 3,3,3,3,3,3,3,3]

  • [3,5,3,5]

  • [-3,-3,-3,7,7,7,7,7]

Mostra soluzione
[18]:
import matplotlib.pyplot as plt
import numpy as np

# scrivi qui il primo grafico


../_images/visualization_visualization1-sol_70_0.png
Mostra soluzione
[19]:
# scrivi qui il secondo grafico


../_images/visualization_visualization1-sol_74_0.png
Mostra soluzione
[20]:
# scrivi qui il terzo grafico


../_images/visualization_visualization1-sol_78_0.png

Aggiungiamo la curva di fitting

✪✪✪ ESERCIZIO 3.2 Tipicamente, quando otteniamo da esperimenti una distribuzione di valori, ci interessa ricavare un modello matematico dei dati osservati. In questo caso, siamo fortunati e già sappiamo qual’è il modello giusto dei dati in segnale, e cioè una distribuzione gaussiana con i parametri mu e sigma. Se oltre all’istogramma facciamo anche un plot in sovraimpressione di una curva gaussiana con quei mu e sigma, dovremmo quindi vedere una linea che segue l’istogramma, che per questo la chiameremo curva di fitting. Per ottenere la curva, possiamo usare i valori usati per dividere le colonne come punti sull’asse x e calcolare i valori corrispondenti sull’asse y: questo può essere fatto utilizzando la libreria scipy.norm e più precisamente il metodo scipy.norm.pdf(), che sta per Normal distribution’s Probability Density Function. A questo metodo si passano:

  • i valori delle x

  • i parametri della normale mu

  • il parametro sigma

e lui restituisce i valori sulla curva di densità corrispondente.

Prova ad aggiungere la funzione di fit come descritto sopra, disegnando una linea tratteggiata con il metodo ax.plot visto in precedenza, aggiungendo le due linee di codice dove segnalato dal commento.

NOTA Come forse hai notato i valori sull’asse y sono cambiati e la funzione ax.hist() ha acquisito un nuovo parametro: density=True: questo serve per normalizzare i valori dell’istogramma dividendo il numero di elementi in ogni bin per il numero totale di elementi e permettendo di comparare l’istogramma con la funzione di probabilità associata.`

Mostra soluzione
[21]:
from scipy.stats import norm
import matplotlib.pyplot as plt
import numpy as np

fig, ax = plt.subplots()  # creiamo Figure and Axes in un comando solo

# generiamo il segnale secondo distribuzione gaussiana

mu = 0  # media
sigma = 1  # sqm
segnale = np.random.normal(mu, sigma, 500) # generiamo 500 valori distribuiti come una gaussiana, e mettiamoli nell'ndarray 'x'

# aggiungiamo l'istogramma
num_bins = 50    # numero di colonne per l'istogramma

# in questo caso hist ritorna tre valori che mettiamo in altrettante variabili
# notare density=True per avere valori tra 0 e 1
n, bins, columns = ax.hist(segnale, num_bins, density=True)

# ESERCIZIO: Inserisci qui le due linee per disegnare la curva di fitting


ax.set_xlabel('Segnale')
ax.set_ylabel('Densità di probabilità')
ax.set_title(r'Istogramma di una Gaussiana con $\mu=0$, $\sigma=1$')
fig.tight_layout()
plt.show()
../_images/visualization_visualization1-sol_83_0.png

Grafici a torta

Nel prossimo esempio abbiamo il celeberrimo grafico a torta (piechart), la cui creazione è semplicissima:

  1. assegnamo delle etichette (labels) a tutti gli spicchi;

  2. decidiamo le quantità (la larghezza degli spicchi) per ogniuno degli spicchi (usando la stessa posizione in cui abbiamo enumerato le etichette in precedenza);

  3. selezioniamo di quanto vogliamo separare ogni spicchio dagli altri (esplodi conterrà questa informazione);

  4. creiamo Figure e Axes

  5. disegnamo la torta usando il metodo pie, questo metodo prende in ingresso le quantità ma ha anche una lunga lista di parametri opzionali, nel nostro caso noi abbiamo usato:

    • labels cioè le etichette da apporre ad ogni spicchio,

    • explode vedi punto 3,

    • autopct è una stringa che serve per stampare la percentuale su ogni fetta, richiede come parametro una stringa di formattazione, in questo caso riserva una cifra intera (%**1**.1f%%) e assegna la precisione ad una cifra decimale (%1.**1**f%%), ed aggiunge il carattere % alla fine (%1.1f**%%** ).

    • startangle è l’angolo di partenza dal quale iniziare a disegnare il grafico, 90 significa la verticale superiore del grafico.

[22]:
import matplotlib.pyplot as plt

labels = ['Pippo', 'Pluto', 'Paperino']
y = [3, 4, 1]
esplodi = [0, 0, 0.1]

fig, ax1 = plt.subplots()
ax1.pie(y, labels=labels, explode=esplodi, autopct='%1.1f%%', startangle=90)
ax1.set_title("Spar(t)izione della pizza")

fig.tight_layout()
#fig.show()
../_images/visualization_visualization1-sol_85_0.png

✪ ESERCIZIO 3.3: copia qua sotto manualmente il codice per disegnare il grafico a torta

Mostra soluzione
[23]:
# scrivi qui


../_images/visualization_visualization1-sol_90_0.png

✪✪✪ ESERCIZIO 3.4 Prova a disegnare una figura con due colonne: in quella di sinistra copia un grafico a torta, e in quella di sinistra metti un grafico a barre verticali utilizzando il metodo ax.bar() (primo parametro la posizione x delle barre e secondo l’altezza) per disegnare un diagramma a barre equivalente. Quale ti sembra più chiaro? Prova a giocare con i parametri e explode startangle, noterai che nel grafico a torta le proporzioni sembrano cambiare, specialmente se la dimensione degli spicchi è simile.

Non diamo qua tutte le istruzioni per visualizzare bene il grafico a barre, prova un po’ a cercare nella documentazione di Matplotlib. Prova anche a:

  • impostare colori uguali a quelli della torta

  • impostare la larghezza delle colonne, provando diversi valori. Domanda: la larghezza delle barre può influire sulla percezione dei valori in chi osserva?

  • mettere le label sotto le barre (più difficile)

Se non ti viene in mente niente puoi sempre guardare la soluzione.

Ricordati sempre che il comando help() è molto importante, usalo quando vuoi sapere di più sui parametri o sulle funzioni che stai utilizzando

Mostra soluzione
[24]:
# scrivi qui


../_images/visualization_visualization1-sol_95_0.png

Abbellire il grafico

Si può migliorare i grafici in vari modi, mettiamo qui qualche esempio.

Colore di sfondo

[25]:
# CAMBIA IL COLORE DI BACKGROUND PER *TUTTI* I GRAFICI SUCCESSIVI
plt.rcParams['axes.facecolor'] = 'azure'
plt.plot([1,2,3],[4,5,6])
plt.show()
../_images/visualization_visualization1-sol_98_0.png
[26]:
plt.rcParams['axes.facecolor'] = 'white'  # rimette il colore bianco per i grafici successivi
plt.plot([1,2,3],[4,5,6])
plt.show()
../_images/visualization_visualization1-sol_99_0.png

Testo

[27]:
plt.xlim(0,450) # importante da settare quando metti testo
plt.ylim(0,600) # perchè matplotlib non riadatta automaticamente le dimensioni per mostrare il testo


plt.text(250,
         450,
         "Ciao !",
         fontsize=40,
         fontweight='bold',
         color="lightgreen",
         ha='center', # centra orizzontalmente il testo
         va='center') # centra verticalmente il testo
plt.show()
../_images/visualization_visualization1-sol_101_0.png

Immagini

Proviamo ad aggiungere l’immagine clef.png

[28]:
%matplotlib inline
import matplotlib.pyplot as plt

fig = plt.figure(figsize=(7,7))

# NOTA: se non vedi niente, controlla posizione e/o zoom factor

from matplotlib.offsetbox import OffsetImage, AnnotationBbox

plt.xlim(0,150)   # importante da settare quando metti immagini
plt.ylim(0,200)   # perchè matplotlib non ridimensiona automaticamente per mostrare le immagini
ax=fig.gca()
img = plt.imread('clef.png')
ax.add_artist(AnnotationBbox(OffsetImage(img, zoom=0.5),
                            (50, 100),
                            frameon=False))

plt.show()
../_images/visualization_visualization1-sol_103_0.png

Intensità del colore

Puoi regolare l’intensità del colore con il parametro alpha che varia da 0.0 a 1.0

[29]:
plt.plot([150,175], [25,400],
         color='green',
         alpha=1.0,  # colore pieno
         linewidth=10)
plt.plot([100,125],[25,400],
         color='green',
         alpha=0.3,  # più leggero
         linewidth=10)
plt.plot([50,75], [25,400],
         color='green',
         alpha=0.1,  # quasi invisibile
         linewidth=10)
plt.show()
../_images/visualization_visualization1-sol_105_0.png

Esercizio - Be fancy

Prova a scrivere del codice per visualizzare l’immagine qui sotto

Mostra soluzione
[30]:
%matplotlib inline
import matplotlib.pyplot as plt

# scrivi qui


../_images/visualization_visualization1-sol_110_0.png

Conclusione matplotlib

Come anticipato questa lezione non copre il 100% dei grafici e delle funzionalità presenti in Matplotlib, quindi la principale risorsa nella quale cercare esempi e documentazione è sicuramente la pagina ufficiale di matplotlib ma esistono altre risorse utili che raggruppano le funzioni utili e le loro interfacce cheatsheet per matplotlib e cheatsheet per numpy.

Grafici SVG

E’ possibile creare velocemente grafici grafici accattivanti senza programmare in siti come Rawgraphs. Una volta creati i grafici, si può esportarli in file SVG e caricarli in Jupyter usando semplice codice Markdown. Un’altro sito da guardare è DataWrapper

Nel caso di grafici interattivi, potresti dover incollare in Jupyter del codice HTML che rappresenta il grafico - vediamo come si fa. In ogni caso tratteremo meglio grafici interattivi creati in Python nel capitolo applicazioni interattive

Importazione in Jupyter come cella HTML

L’HTML è il codice con cui sono scritte le pagine web. Usando i comandi ‘magici’ di Jupyter %%HTML è possibile importare dei frammenti di codice HTML nelle celle. Qua riportiamo solo qualche esempio, vedremo meglio l’HTML nel tutorial sull’estrazione .

ATTENZIONE: le celle HTML NON sono visualizzate nei PDF esportati!

Google Calendar

Se vai nelle impostazioni di un Google Calendar, vedrai che c’è una voce ‘Incorpora codice’ con dentro del codice che inizia con <iframe>.

Se copi quel codice in Jupyter, ricordandoti di mettere %%HTML nella prima cella vedrai il calendario.

[31]:
%%HTML

<iframe src="https://calendar.google.com/calendar/embed?src=h5tv130eddjl9mmgh55hr2ak7k%40group.calendar.google.com&ctz=Europe%2FRome&dates=20180201%2F20180401" style="border: 0" width="800" height="600" frameborder="0" scrolling="no"></iframe>

Video YouTube

Se in YouTube sotto un video clicchi su CONDIVIDI e poi scegli incorpora, vedrai del codice che inizia con <iframe>. Puoi incollare tale codice in Jupyter in una cella, basta che nella prima riga scrivi %%HTML

[32]:
%%HTML

<iframe width="560" height="315" src="https://www.youtube.com/embed/jeG49DxMsvw" frameborder="0" allow="autoplay; encrypted-media" allowfullscreen></iframe>

Mappa Umap

Sempre tramite è possibile inserire mappe, per esempio UMap - qua vediamo solo un’esempio, vedremo i dettagli nel tutorial sull’integrazione.

NOTA: Queste mappe permettono di essere cliccate e sono spesso più che sufficienti per scopi di viusalizzazione / browsing, ma non è possibile scrivere del codice Python che reagisca ai click. Se hai questa esigenza, bisogna usare sistemi più avanzati discussi nel tutorial Interfacce utente

Questa che segue è la mappa Umap dei Servizi di Rovereto (tutorial creazione mappa)

[33]:
%%HTML

<iframe width="100%" height="300px" frameBorder="0" allowfullscreen src="https://umap.openstreetmap.fr/it/map/servizi-rovereto_41127?scaleControl=false&miniMap=false&scrollWheelZoom=false&zoomControl=true&allowEdit=false&moreControl=true&searchControl=null&tilelayersControl=null&embedControl=null&datalayersControl=true&onLoadPanel=undefined&captionBar=false#14/45.8883/11.0500"></iframe><p><a href="https://umap.openstreetmap.fr/it/map/servizi-rovereto_41127">Visualizza a schermo intero</a></p>

Esportare fogli Jupyter

Puoi esportare un singolo foglio Jupyter in diversi formati:

  • formato PDF: File->Download as-> PDF via Latex (.pdf)

  • sito a pagina singola in formato HTML: File->Download as-> HTML (.html)

Per esportare un insieme di fogli Jupyter a intero sito HTML / mega PDF, puoi usare NBSphinx - usato anche per generare tutto il sito di SoftPython a partire da fogli Jupyter (vedi anche codice di SoftPython su Github) !

Prosegui

Continua con la challenge