Matplotlib - appunti
Posted on 07/11/2021, in Italiano. Reading time: 86 minsMatplotlib
Queste sono le mie (Paolo Avogadro) note basate sul video di Derek Banas riguardo a Matplotlib. Oltre agli esempi suggeriti aggiungo dei miei test e considerazioni. Qualunque errore e’ esclusivamente dovuto ad una mia erronea interpretazione dei comandi. Lo scopo di queste note non e’ di presentare esempi perfettamente funzionanti, ma serve a me come spunto per ricordare i comandi di Matplotlib, e il modello mentale che io ho sul pacchetto. La versione originale di queste note ha la forma di un Jupyter Notebook e quindi possono esserci dei riferimenti ai notebook all’interno del testo. Dopo avere imparato Matplotlib puo’ essere interessante impararare ad usare Seaborn.
Cerco di ricostruire gli esempi presentati e fare delle piccole varianti per capire meglio. Queste note suppongono che ci sia una certa conoscenza di base di come fare i grafici al computer, per esempio partendo da Gnuplot.
Notazione:
- cerco di usare l’evidenziatore per i
comandi
- cerco di usare il grassetto per i termini principali
Micro-riassunto:
Ci sono 2 modi principali per fare un grafico:
-
modo veloce: con le funzioni di plotting, per esempio:
plt.plot(x_1, y_1)
(dove x_1 e x_2 sono due oggetti contenenti lo stesso numero di variabili). Si possono inoltre aggiungere delle funzioni per controllare le label, il titolo ecc. -
modo esteso:
- prima si definisce una figure, per esempio:
fig_1 = plt.figure(figsize=(5,4), dpi =100);
pensa alla figure come un’immagine bianca. - poi si costruisce uno (o piu’) axes (assi) con un metodo delle figure:
axes_1 = fig_1.add_axes([0.1,0.1,0.9,0.9])
(dove specifichiamo la posizione degli assi all’interno della figura). Gli assi determineranno la posizione del grafico. Per esempio se hai un solo quadrante per il tuo grafico puoi immaginare gli assi come un rettangolo (vuoto all’interno). - A questo punto si fa partire un grafico, usando un metodo degli assi, per esempio:
axes_1.plot(x_1,y_1);
Nota che questi metodi sono in pratica le stesse funzioni del punto 1 (solo che vengono chiamati come metodi dell’asse).
- prima si definisce una figure, per esempio:
Nota
- se non sei in un jupyter notebook dovrai usare un
plt.show()
- se sei su un notebook invece, serve un magic command (e’ una di quelle cose decorate con il percentuale), ci sono vari di questi comandi, tra cui:
%matplotlib inline
(questo fa apparire delle immagini png statiche nel notebook)%matplotlib notebook
(si possono fare zoom delle immagini)%matplotlib tk
(tkinter GUI)
Una lista di termini utili:
alpha=0.75
definisce la trasparenzalw=2
larghezza delle linee del graficols ='-.'
line style, se e’ una linea continua, oppure trattino e punto, ecc…marker = 'o'
marker sono i punti di gnuplot. Cosa viene messo nei punti? in questo caso dei cerchietti =o)markersize=7
la grandezza dei puntimarkerfacecolor ='y'
il colore dell’interno dei puntimarkeredgecolor='k'
il colore dei contorni dei puntimarkeredgewidth=2
la larghezza del contorno dei puntiprojection='3d'
argomento per quando si creano degli assi e devono avere un 3Dgoog_df = pd.read_csv('GOOG.csv', index_col = 0, parse_dates=True)
trasforma del testo in datetime!facecolor
e’ il colore dello sfondo di un’immagine
Metodi di FIGURE:
fig.tight_layout()
oppure,plt.tight_layout()
serve per evitare sovrapposizioni per esempio i numeri degli assi trasbordinofig_3.savefig('ultimoPlot.png')
salvare a file una figura!
Metodi degli Assi
plt.xticks(np.linspace(0,5,5), ('Tom', 'Dick', 'Harry', 'Sally', 'Sue'))
tics (o ticks) sull’asse x. Per non avere ticks:plt.xticks([])
(non ho messo nulla nella lista = non ci sono ticks)axes_3.set_xlim([0,3])
definisce i limiti sull’asse x (set xlim[1:100])axes_4.set_xlabel('temp')
label degli assiaxes_3.grid(False, color='r', dashes=(0,2,1,2))
mette una griglia sullo sfondo, occhio che color e’ il colore della griglia non dello sfondo.plt.grid(False)
eplt.grid(b=None)
tolgono la grigliaaxes_3.set_facecolor('w')
colore dello sfondo (bianco in questo caso)axes_4.set_title('da Pandas: IceCream')
titoloaxes_1.legend(loc =0 )
# Loc=0 e’ la migliore location scelta da lui`
Tipi di disegno (possono essere chiamati come metodi degli assi o funzioni plt):
axes_4.plot(x_2, y_2)
disegno standard in cui ci sono i punti e posso unirli, cambiarli ecc.plt.bar(x_2, y_2, width=1.5);
barchart (come istogramma ma sulle x possono essere categorici)plt.stem(x_2, y_2, '-.')
impulsi, interessante si puo’ indicare il tipo di lineaplt.hist(arr3ok, bins= 7, density=True, stacked =False);
istogrammi (raggruppa i valori sull’asse delle x in bins)plt.pie()
piechart TORTE (gurada sotto perche’ servono un po’ di dettagli)axes_13.scatter(dr_arr, test_arr, s=cc_arr_sm, c=color_arr, alpha=0.2 )
scatterplot valori sull’asse delle x, y, dimensione punti, colori dei punti, trasparenza)axes_9.scatter3D(x_3,y_3,z_3, c=z_3, cmap='Blues');
scatterplot 3Daxes_9.contour3D(x_4,y_4,z_4, 20, cmap='Blues');
3D contorno, curve di livello, isoipseaxes_9.plot_wireframe(x_4,y_4,z_4, cmap='Blues');
wireframe e’ il grafico 3D standard di gnuplot, collega tutti i puntiaxes_9.plot_surface(x_4,y_4,z_4, rstride=1, cstride=1, cmap='Blues', edgecolor='r');
3D, collega i punti e colora le tegole
Consiglio: in un Jupyter notebook usa shift-tab su una funzione per vederne la sua descrizione (prima devi cliccare sulla cella e poi avere il cursore sulla funzione stessa).
Consiglio questo articolo contiene trucchi su jupyter notebook e alternative a Matplotlib.
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
%matplotlib inline
#%matplotlib notebook
%reload_ext autoreload
%autoreload 2
Functional Plot
Cominciamo con un’immagine semplice in cui
- c’e’ il titolo:
plt.title('ciao')
- ci sono i nomi degli asssi:
plt.xlabel('Days')
- c’e’ un grafico:
plt.plot(x_1, y_1)
Quando faccio un disegno, voglio che tutte le coordinate x siano in un contenitore (lo stesso vale per le coordinate y). Questi “contenitori” devono contenere lo stesso numero di oggetti, altrimenti per un punto avrei solo la coordinata x o solo la y… quindi mi manca il punto!
x_1 = np.linspace(0,5,10) # genera un Numpy array con 10 float equispaziati tra 0 e 5
y_1 = x_1 **2 # genera un Numpy array che e' il quadrato del primo
plt.plot(x_1, y_1);
plt.title('ciao');
plt.xlabel('Days');
plt.ylabel('Days squared');
#plt.show() # se non siamo in jupyter notebook
Domanda
: posso passare delle liste ad un plt.plot()
?
Risposta
: si’ certo! posso anche graficare delle liste che contengano delle stringhe. Se il contenitore di stringhe e’ una lista, allora esiste un ordine per le stringhe e questo ordine verra’ usato nella visualizzazione. Per un set
invece non esiste un ordine e si ha un errore TypeError: unhashable type: ‘set’
l1= [1,2,3,4]
l2= [3,4,5,6]
l3= ['a','b','e','d']
d1 = {"apple", "banana", "cherry"}
plt.plot(l1,l3);
#plt.plot(l1,d1) # non funge!
plt.subplot() molti grafici in modo veloce
Qui vediamo come mettere piu’ di un grafico vicino all’altro. Nel dettaglio usando subplot
potremo costuire una griglia, in ogni casella della griglia verra’ messo un grafico.
Il comando plt.subplot(1,2,1)
fa questo tipo di lavoro.
- il primo argomento e’ il numero di righe della griglia (in questo caso c’e’ solo una riga)
- il secondo argomento e’ il numero di colonne della griglia .
- il terzo argomento e’ l’indice del grafico. L’indice ci dice in quale casella della griglia stiamo mettendo il subplot. L’ordine seguito e’ lo stesso che si ha quando si legge: da SINISTRA a DESTRA da SOPRA a SOTTO.
Vediamo un esempio:
# nota che se anche il terzo argomento e' 2 il grafico appare al primo posto, perche'
# non ce ne sono 2! E' un po' come se cadesse a sinistra se ci sono dei buchi?
plt.subplot(1,2,2) # questo ci dice che abbiamo una riga e 2 colonne
plt.plot(x_1,y_1, 'r'); # r = red
plt.subplot(1,2,1) # questo ci dice che abbiamo una riga e 2 colonne
plt.plot(x_1,y_1, 'r') # r = red
plt.subplot(1,2,2) # se metto 1 mi sovrappone con il primo ma mi dice che c'e' qualcosa di strano
plt.plot(x_1,y_1, 'b')
[<matplotlib.lines.Line2D at 0x2de659e5c40>]
plt.subplot(2,2,1) #
plt.plot(x_1,y_1, 'r') #
plt.subplot(2,2,2) #
plt.plot(x_1, y_1-y_1**2, 'b')
plt.subplot(2,2,4)
plt.plot(x_1, -y_1, 'g');
plt.tight_layout() # evita sovrapposizione dei numeri dei grafici!
Figure e axes
- Una figure e’ un oggetto su cui poi si mette il grafico (lo vedo come la tela bianca su cui fare il disegno)
- contiene tutti i ‘plot elements’
- puo’ contenere molti axes (assi), che in pratica sono gli assi che definiscono il disegno vero e proprio, in quanto i punti sono riferiti agli assi.
- posso definire la sua larghezza e lunghezza in inch (inch=2.54 cm), probabilmente posso cambiare scala:
figsize=(5,4)
- posso anche definire la risoluzione in dpi
- ATTENTO se definisci il numero di dpi, quando lo visualizzi come un png, questo definisce la dimensione della figura a video! quindi sembra che figsize non funzioni!
fig_1 = plt.figure(figsize=(5,4), dpi =100);
<Figure size 500x400 with 0 Axes>
Axes
L’oggetto axes (come indica il nome) identifica la posizione, la forma, e tutte le caratteristiche degli ASSI di un grafico. Se non facciamo esplicitamente un grafico, ci saranno solo le due fracce perpendicolari (gli assi) con dentro nulla. Possiamo i plot (grafici) sono dei metodi degli assi! La logica e’ quindi che siano un oggetto in funzione di dove sono gli assi (e ha senso, quando uno fa un grafico su un foglio, prima disegna gli assi, e poi puo’ definire la posizione dei punti che compongono il grafico. In questo senso quindi il plot e’ stato definito come un metodo di un axes. Nota che posso mettere piu’ di un axes su una singola figure. Anche questo e’ intuitivo, posso mettere 2 grafici sullo stesso foglio, poi i punti di un grafico saranno riferiti ad un paio di assi e quelli del secondo ad un altro paio di assi. Gli assi definiscono il sistema di riferimento “inerziale” che determina la posizione dei punti!
Gli assi vengono costruiti su una figure
tramite questo metodo:
axes_1 = fig_1.add_axes([0.1,0.1,0.9,0.9])
Significa che axes_1
sara’ un rettangolo il cui:
- punto in basso a sx ha coordinate 0.1, 0.1 (rispetto a fig_1). Ovvero, la figure e’ un rettangolo, anche gli axes sono un rettangolo, il cui punto in basso a sinistra si trova nelle coordinate che sono il 10% delle x e il 10% delle y del punto in basso a sx della figure.
-
punto in alto a dx ha coordinate 0.9,0.9 (rispetto a fig_1) In questo modo ho un grafico che e’ piu’ piccolo del “canvas” definito da fig_1.
- (nel video) non e’ chiaro come ha fatto l’esponente 2 sulla x. Io devo usare i comandi Latex
Attenzione, io avevo messo il comando fig_1 = plt.figure(figsize=(5,4), dpi =100)
in una cella diversa
da dove facevo il axes.plot. Per questo non vedevo nulla!! Bisogna creare la figura nella stessa cella di Jupyter!
Quindi ricapitolando:
- creo un oggetto
figura
( me lo immagino come un foglio bianco di una certa dimensione) - creo un oggetto
axes
che e’ ottenuto da un metodo dellafigura
( e’ il grafico vero e proprio, definito dagli assi sopra, sotto e destra e sinistra. Al suo interno posso poi mettere dei disegni tramite il metodo plot) - tramite metodi di
axes
aggiungo delle caratteristiche come le label - tra i metodi di un axes c’e’
plot
(e altri tipi di grafico che potrei fare direttamente con plt). Chiamando un metodo che disegna da un axes, il grafico viene messo su questo axes. - posso aggiungere piu’ di un grafico sullo stesso axes, basta chiamare piu’ volte un metodo che disegna sull’axes.
- nota che si deve fare un axes.plot per ognuno dei disegni che voglio compaiano nella figura!
fig_1 = plt.figure(figsize=(5,4), dpi =100) # istanzio una FIGURA chiamata 'fig_1'
axes_1 = fig_1.add_axes([0.1,0.1,0.9,0.9]) # istanzio un AXES (axes_1), della figura 'fig_1'
axes_1.set_xlabel('Days new') # LABEL degli assi
axes_1.set_ylabel('Days squared new') # LABEL degli assi
axes_1.set_title('Ciao new') # TITOLO degli assi
axes_1.plot(x_1, y_1, label = 'x/x$^2$') # GRAFICO 1 (all'interno di axes_1)
axes_1.plot(y_1, x_1, label = 'x^2/x') # GRAFICO 2 (all'interno di axes_1)
axes_1.legend(loc =0 ) # Loc=0 e' la migliore location scelta da lui
# 1=alt dx; 2=alto sx; 3=basso sx, 4 basso dx
# oppure si fornisce una tupla di x e y dall'angolo in basso a sinistra
tu = (0.3, 0.4) # (tupla) questi valori sono in frazione rispetto alla grandezza totale, vedi sotto
axes_1.legend(loc=tu ); # posizione della legenda
Molte curve: versione veloce
se devo fare un grafico veloce, basta che passo le x e y di tutti i grafici in ordine
al plot, in questo modo verranno visualizzati tutti! Se non metto color='black'
di default le due curve avranno colori diversi
plt.plot(x_1, y_1, x_1, y_1/3); # disegna le 2 funzioni
Axes innestati
Voglio ora inserire piu’ di un axes
nella stessa figura. In pratica aggiungo un axes all’esempio precedente.
Per fare questo devo creare un altro axes, proprio perche’ in questo caso i dati si riferiscono ad assi diverse che devono essere definite.
Ricapitolando:
- nell’esempio sopra ci sono una curva blu e una arancione, sono comunque riferite allo stesso axes. Questi axes vanno da 0 a 25 (circa).
- se voglio inserire una figura nuova, i punti di questa figura saranno riferiti a un nuovo sistema di assi, ho quindi bisogno di inserire questi nuovi assi, creando un nuovo oggetto axes (con un nome diverso)
- dovro’ quindi indicare dove si collocano questi nuovi assi rspetto alla
figure
- dovro’ anche indicare la loro grandezza, anche in questo caso rispetto alla
figure
Testo nella figura
- per inserire un testo nel disegno si usa il metodo
text
diaxes
. - Le coordinate sono riferite all’
axes
e partono dal basso a sinistra. - Nota che nel disegno sotto ho 2 axes, e il messaggio e’ riferito ad
axes_2
. Questo e’ ovvio perche’ e’ chiamato come un metodo di questo axes - Nota inoltre che
axes_2.text(0,40,'message')
fa uscire dal disegno, in quanto per il disegno l’asse delle y arriva solo fino a circa 25!
nell’esempio di qui sotto:
- il primo axis contiene due curve
- il secondo axis contiene una curva
fig_1 = plt.figure(figsize=(5,4), dpi =100) # FIGURA 1
assi_1 = fig_1.add_axes([0.1,0.1,0.9,0.9]) # ASSI_1
assi_1.set_xlabel('Days new')
assi_1.set_ylabel('Days squared new')
assi_1.set_title('Ciao new')
assi_1.plot(x_1, y_1, label = 'x/x$^2$') # GRAFICO 1 (degli "ASSI_1")
assi_1.plot(y_1, x_1, label = 'x^2/x') # GRAFICO 2 (degli "ASSI_1")
assi_1.legend(loc =0 ) # Loc=0 e' la migliore location scelta da lui
######## costruisco i secondi assi #####################
assi_2 = fig_1.add_axes([0.45, 0.45,0.4,0.3]) # ASSE 2
assi_2.set_xlabel('Days new')
assi_2.set_ylabel('Days squared new')
assi_2.set_title('Ciao dentro')
assi_2.plot(x_1, y_1, 'r') # GRAFICO 2 # GRAFICO 1 (degli "ASSI_2")
#assi_2.text(0,40, 'Message') # testo
assi_2.text(0,40, 'Message') # testo
Text(0, 40, 'Message')
subplots() Una griglia di grafici
OCCHIO: plt.subplots()
$\neq$plt.subplot()
(il primo termina in s)
Il singolo comando subplots
in pratica costruisce 2 oggetti:
- una figure
- una array di assi (ma un array di numpy puo’ contenere degli oggetti strani? non erano solo numeri? no! basta che in tutti gli oggetti siano dello stesso tipo: omogeneita’ degli array).
- devo quindi descrivere/inizializzare ognuno dei possibili axes dell’array, altrimenti ho solo gli assi senza nessun disegno dentro.
In pratica e’ una specie di scorciatoia per ordinare facilmente degli axis in una figure in modo che siano esattamente alle posizioni della griglia che viene definita con il comando, per esempio indicando il numero di colonne e di righe. Altrimenti avrei potuto istanziare una figura, e istanziare tanti axes stando attento a metterli nel posto giusto all’interno della figura.
Attenzione se voglio mettere degli axes aggiuntivi (oltre all’array di axes iniziale), posso farlo, occhio pero’ che si riferiranno tutti alla figure
per quanto riguarda la posizione e non avranno un particolare ordinamento o forma. Dovro’ essere io a stare attento a metterli nel posto corretto e con la forma corretta!
-
il comando
plt.tight_layout()
aiuta a non fare sovrapporre le label. - Attento che devi usare il nome della figura corretto
fig_2
- Attento: non usare un nome gia’ usato per un altro axes, come
axes_2
- Attento: la dimensione del subplot e’ riferita al figsize, non all’axes di cui e’ subplot. Per questo trasborda!
- Attento: se costruisci un nuovo axes viene messo sopra l’axis genitore, e per questo lo (puo’) coprire.
- Di default un axes non e’ trasparente!
fig_2 , axes_2 = plt.subplots(figsize=(8,4), nrows=1, ncols= 3)
plt.tight_layout() # evita la sovrapposizione delle label
axes_2[1].set_title('Plot 2')
axes_2[1].set_xlabel('x')
axes_2[1].set_ylabel('x quadro')
axes_2[1].plot(x_1, y_1)
# Nuovo AXES che non fa parte dell'array creato con subplots
axes_3 = fig_2.add_axes([0.45, 0.45,0.4,0.4])
axes_3.set_xlabel('Days new')
axes_3.set_ylabel('Days squared new')
axes_3.set_title('Ciao straripante')
axes_3.plot(x_1, y_1, 'r') # GRAFICO 2
axes = fig_2.add_axes ([0.085,0.15,0.2,0.7])
axes.plot(x_1,y_1, 'co')
axes.set_title('Dentro')
Text(0.5, 1.0, 'Dentro')
f , a = plt.subplots(figsize=(8,4), nrows=1, ncols= 3)
plt.tight_layout()
############ Axes Centrale ###############
a[1].set_title('Centrale')
a[1].set_xlabel('x')
a[1].set_ylabel('x quadro')
a[1].plot(x_1, y_1)
############ Axes Ciao Dentro ############
a1 = f.add_axes([0.45, 0.45,0.4,0.4])
a1.set_xlabel('Days now')
a1.set_ylabel('Days squared new')
a1.set_title('Tra centro e sinistra')
a1.plot(x_1, y_1, 'r') # GRAFICO 2 della figura centrale
############ Axes Sinistro ###############
a[0].set_title('Sinistra')
a[0].set_xlabel('x')
a[0].set_ylabel('x quadro')
a[0].plot(x_1, -y_1,'g')
############ Axes Piccolo sinistra ######
a0 = f.add_axes([0.1, 0.25,0.2,0.2])
a0.set_xlabel('Days old')
a0.set_ylabel('Days squared new')
a0.set_title('Piccolo Sinistra')
a0.plot(x_1, y_1, 'r') # GRAFICO 2 della figura centrale
[<matplotlib.lines.Line2D at 0x2de66e3a190>]
Colori e Apparenza
I colori di default sono:
- r = red
- c = cyan
- m = magenta
- y = yellow
- k = black
- w = white
Inoltre
- color=”0.75” crea un 75% gray (e’ una percentuale di black)
- si possono usare i colori con hexcodes color=”#eeefff”
-
si possono usare i colori tipo color=”burlywood” che si trovano a https://en.wikipedia.org/wiki/Web_colors
lw
come gnuplot, ma devo mettere l’uguale, p.es.lw=2
- ls ‘-.’ si trovano qui: https://matplotlib.org/3.1.0/gallery/lines_bars_and_markers/linestyles.html
- marker sono i punti: https://matplotlib.org/3.3.3/api/markers_api.html
- markersize = grandezza del punto
- markerfacecolor = colore di riempimento del punto
- makeredgecolor = colore del bordo del punto
fig_3 = plt.figure(figsize=(6,4))
axes_3 = fig_3.add_axes([0,0,1,1])
axes_3.plot(x_1, y_1, color='navy', alpha=0.75, lw=2, ls ='-.', marker = 'o',
markersize=7, markerfacecolor ='y', markeredgecolor='k', markeredgewidth=2)
[<matplotlib.lines.Line2D at 0x2de66eaa970>]
Grandezza degli assi e background
I comandi per gestire gli assi assomigliano a quelli di gnuplot, ma solo un po’ piu’ “verbose”, in cui si deve scrivere di piu’.
Possimo anche mettere una griglia e il background color.
- axes_3.
set_xlim([0,3])
limiti asse x - axes_3.
grid(True, color='0.6', dashes=(5,2,1,2))
caratteristiche della griglia (NON dello sfondo!), dashes mette delle linee tratteggiate attraverso il disegno. Quindi qui sono le righe che partono da un tic e arrivano dall’altra parte del disegno - axes_3.
set_facecolor('#FAEBD7')
colore di sfondo
fig_3 = plt.figure(figsize=(3,4) )
axes_3 = fig_3.add_axes([0,0,1,1])
axes_3.plot(x_1, y_1, color='navy', alpha=0.75, lw=2, ls ='-.', marker = 'o',
markersize=7, markerfacecolor ='y', markeredgecolor='k', markeredgewidth=2)
axes_3.set_xlim([0,3])
axes_3.set_ylim([0,25])
#axes_3.grid(True, color='0.6', dashes=(5,2,1,2)) # mettiamo una griglia non lasciamo vuoto
axes_3.grid(False, color='r', dashes=(0,2,1,2))
#axes_3.set_facecolor('#FAEBD7')
axes_3.set_facecolor('w')
Salvare una figura a file
strano quando lavoravo con Seaborn sembrave che il save dovesse avvenire nella stessa cella dove si faceva il disegno.
- Basta mettere il nome dell’estensione e lui salva correttamente nel formato corrispondente
fig_3.savefig('ultimoPlot.png')
Pandas
Qui usiamo l’ICE CREAM data table (che diventera’ un DataFrame). Ho copiato il dataframe del video.
-
Assegno dei nomi alle colonne del csv, mentre leggo il file:
ics_df = pd.read_csv('icecream.csv', names=['temps', 'sales'])
. Nota che io ho usato i nomi sales e temps (temperatures). Lui li aveva con la prima lettera in maiuscolo. Temp e’ in Farenheit, e sales e’ in unita’ di gelato. -
Se non usassi il parametro
names=...
lui prenderebbe la prima riga e la trasformerebbe nei nomi delle colonne (e i valori della prima riga non sarebbero accessibili)! -
Osservazione: il metodo dei DataFrame
sort_values(by='temps')
lavora inplace, quindi modifica il df!
ics_df = pd.read_csv('icecream.csv', names=['temps', 'sales'])
ics_df.head()
temps | sales | |
---|---|---|
0 | 37 | 292 |
1 | 40 | 228 |
2 | 49 | 324 |
3 | 61 | 376 |
4 | 72 | 440 |
Attento sort_values()
lavora inplace
ics_df = ics_df.sort_values(by='temps') # LAVORA INPLACE
A questo punto lui fa delle cose che sembrano non necessarie. Prende e converte il DataFrame in un array di Numpy. Poi prende e scrive le x e le y da questo array di numpy. In effetti ho notato in una sezione sotto che alle volte e’ davvero meglio avere dei numpy array invece che i dataframe, in particolare per evitare dei valori strani sull’asse delle x.
# con numpy array ###############
# np_arr = ics_df.values # prende solo i valori, rimuove le etichette
# x_2 = np_arr[:,0] # seleziono colonna 0
# y_2 = np_arr[:,1] # seleziono colonna 1
###################################
# Alternativa:
x_2 = ics_df.temps # non sono array di np, ma serie di Pandas vanno bene lo stesso
y_2 = ics_df.sales # ricorda puoi usare l nome di una colonna per selezionare tutta le colonna come se fosse un attributo
#x_2 = np.array(ics_df.temps) # NON serve... ora, ma in alcuni casi si'
#y_2 = np.array(ics_df.sales) # NON serve... ora, ma in alcuni casi si'
ok ma fino a qui, dove ha usto il fatto che sia Pandas?
fig_4 = plt.figure(figsize=(6,4))
axes_4 = fig_4.add_axes([0,0,1,1]) # prendo tutto lo spazio, dall'angolo in basso a sx a quello in alto a dx
axes_4.set_title('da Pandas: IceCream')
axes_4.set_xlabel('temp')
axes_4.set_ylabel('sales')
axes_4.plot(x_2, y_2, marker='+'); # ho messo sui punti le crocette come in Gnuplot
Annotare la figura
Se voglio mettere delle annotazioni nel grafico, come per esempio delle frecce, devo usare un metodo degli axes chiamato annotate
. Vediamo nel dettaglio il comando:
axes_4.annotate('Good Month', xy=(83, 536), xytext=(60,520), arrowprops= dict(facecolor='black', shrink=0.0, width=0.5))
'Good Month'
e’ il testo che viene inseritoxy=(83,536)
e’ il punto di arrivo della frecciaxytext=(60,520)
e’ il punto di partenza del testo orizzontale
All’interno di arrowprops
si hanno vari parametri (si deve passare un dizionario con tutti gli argomenti)
facecolor
= ‘black’shrink=0.5
indica quanto piu’ corta deve essere la freccia, rispetto alla lunghezza massima che va dalla fine del testo al punto di arrivo della freccia.width=0.5
possiamo anche allargare la larghezza
fig_4 = plt.figure(figsize=(6,4))
axes_4 = fig_4.add_axes([0,0,1,1]) # prendo tutto lo spazio, dall'angolo in basso a sx a quello in alto a dx
axes_4.set_title('da Pandas: IceCream')
axes_4.set_xlabel('temp')
axes_4.set_ylabel('sales')
axes_4.plot(x_2, y_2)
axes_4.annotate('Good Month', xy=(83, 536), xytext=(60,520),
arrowprops= dict(facecolor='black', shrink=0.0, width=0.5))
Text(60, 520, 'Good Month')
bar() Barchart sotto il grafico
bar()
e’ un metodo di plt
Se voglio fare aggiungere anche le barchart sotto il grafico, basta disegnare ANCHE loro!
Attento ho fatto 2 plot:
- il primo e’ dato da
axes_4.plot(x_2, y_2)
ed e’ passato come un metodo degli assi - il secondo e’ un grafico veloce ed e’ una funzione di matplotlib:
plt.bar(x_2, y_2, width=1.5);
fig_4 = plt.figure(figsize=(6,4))
axes_4 = fig_4.add_axes([0,0,1,1]) # prendo tutto lo spazio, dall'angolo in basso a sx a quello in alto a dx
axes_4.set_title('da Pandas: IceCream')
axes_4.set_xlabel('temp')
axes_4.set_ylabel('sales')
axes_4.plot(x_2, y_2)
axes_4.annotate('Good Month', xy=(83, 536), xytext=(60,520),
arrowprops= dict(facecolor='black', shrink=0.0, width=0.5))
plt.bar(x_2, y_2, width=1.5);
Impulsi stem() e proprieta’ setp()
In gnuplot mettevo with impulses quando volevo che il grafico avesse delle linee verticali che partono dall’asse x e raggiungono ogni punto. Il comando descritto qui sopra bar()
non e’ l’ideale per ottenere questo risultato in quanto la larghezza dell’impulso puo’ creare problemi, meglio usare la funzione:
plt.stem()
mentre posso decidere di colorare l’asse sotto tramite la funzione set property:
plt.setp()
Questa funzione puo’ essere usata per vari oggetti!
fig_4 = plt.figure(figsize=(6,4))
axes_4 = fig_4.add_axes([0,0,1,1]) # prendo tutto lo spazio, dall'angolo in basso a sx a quello in alto a dx
axes_4.set_title('da Pandas: IceCream')
axes_4.set_xlabel('temp')
axes_4.set_ylabel('sales')
axes_4.plot(x_2, y_2)
axes_4.annotate('Good Month', xy=(83, 536), xytext=(60,520),
arrowprops= dict(facecolor='black', shrink=0.0, width=0.5))
markerline, stemlines, baseline = plt.stem(x_2, y_2, '-.')
plt.setp(baseline, 'color', 'r', 'linewidth', 2)
[None, None]
TeX - regular expressions
possiamo usare Latex per scriver formule matematiche usando per esempio $\frac{1}{2}$
- IMPORTANTE nota che nel tutorial ha usato:
r'$\alpha \beta \gamma$'
non ha semplicemente messo ‘’ perche’ cosi’ prende leregular expression
, come il dollaro e lo slash.
Ovvero la scrittura r’ciao $\frac{2}{3}’ crea una stringa che pero’ ha delle regular expression che vengono valutate ed eseguite.
- basta poi ricordare i comandi di Latex
- il metodo
.text
degli ‘axes’ mette ha all’inizio le coordinate (separate da una virgola), poi una virgola con il testo da inserire.
fig_5 = plt.figure(figsize=(5,4), dpi=100)
axes_5 = fig_5.add_axes([0.1, 0.1, 0.9, 0.9]) # costruisco un axes
axes_5.text(0,23, r'$\alpha~ \beta~ \gamma ~ \frac{1}{2} ~\Sigma$') # prima le coordinate del testo, poi il testo
axes_5.plot(x_1, y_1)
[<matplotlib.lines.Line2D at 0x2de66ff15e0>]
Istogrammi plt.hist()
Alcuni argomenti utili per gli istogrammi:
stacked=True
Simuliamo probabilita’ di lancio di 2 dadi. Ci sono 11 possibili valori per la somma:
- 1+1 =2 I
- 1+2 =3 II
- 1+3 =4 III
- 1+4 =5 IV
- 1+5 =6 V
- 1+6 =7 VI
- 2+6 =8 VII (nota che tutti gli altri valori di (2+qualcosa) danno dei risultati gia’ ottenuti)
- 3+6 =9 VIII
- 4+6 =10 IX
- 5+6 =11 X
- 6+6 =12 XI Come altri parametri:
density=True
mostra la frequenza di ogni bin (se e’ falso mostra il conteggio)stacked=True
cosa fa?
Attento: ricorda che il numero di bins
puo’ portare a risultati MOLTO fuorvianti. Per esempio se scegliamo bins=7
otteniamo un oggetto bicefalo attorno al centro. Se invece scegliamo bins=11
otteniamo una campana!
arr_1 = np.random.randint(1,7,5000) # genera 5000 numeri interi tra 1 e 6
arr_2 = np.random.randint(1,7,5000) # genera 5000 numeri interi tra 1 e 6
arr_3 =arr_1+arr_2
arr3ok = arr_3
plt.hist(arr3ok, bins= 7, density=True, stacked =False);
plt.hist(arr_3, bins= 11, density=True, stacked =True);
ax[0].hist() Axes e istogrammi
Qui sotto provo a combinare axes e istogrammi.
- Ho supposto di poter usare il metodo
hist()
direttamente su un asse invece che dover usare unplt.hist
, ovvero:axes.hist(...)
Funge!
fig , ax = plt.subplots(figsize=(8,4), nrows=1, ncols= 2)
#plt.tight_layout()
ax[0].hist( arr_3, bins= 11, density=True, stacked =True);
ax[1].hist( arr_3, bins= 11, density=False, stacked =False);
altri argomenti che si possono passare:
Range
deve essere una tupla con il range di cui si e’ interessaticumulative =True
costruisce la CDF (cumulative distribution function) dati i valori. Attento non me lo prendeva (diceva qualcosa riguardo l’oggetto kernel). Non ho lanciato tutte le altre celle, ma solo quelle iniziali con gli header e quelle della cella Istogrammahisttype= 'step'
genera un grafo con le linee (ma vuoto)color = 'orange'
colora di arancione…orientation = 'horizontal'
gira di 90 gradi l’istogramma posso combinare anche due istogrammi insieme come con gli altri plot.
plt.hist(arr_3, bins= 11, density=True, stacked =True, cumulative=True,
histtype='step', color='blue', orientation= 'horizontal');
Bar charts
Che differenza c’e’ tra un grafo a barre e un istogramma? de facto nell’istogramma si mettono le frazioni e le “barre” sono attaccate l’una all’altra. In un bar chart invece si hanno i numeri e le barre non sono attaccate l’una all’altra, questo perche’ sull’asse delle x spesso non si hanno dei valori numerici, ma categorici (come nell’esempio riportato sotto, dove l’ordine delle colonne e’ sostanzialmente arbitrario).
Per un grafo a barre, si chiama la funzione seguente:
plt.bar(spc, m_eng,width=larghezza, label='maschi', edgecolor ='k')
- il primo argomento contiene la lista/tupla con i nomi che appaiono sull’asse delle x (dato che spesso lo usiamo per variabili categoriche dobbiamo indicare le label), oppure le posizioni delle barre (se ho le posizioni dovro’ poi aggiungere le label sull’asse)
- Attento se nella prima tupla ci sono dei nomi, allora le loro posizioni sono equispaziate automaticamente. Se io aggiungo un altro bar chart, questo secondo viene messo dopo quelle gia’ esistenti.
- Attento se invece nella prima tupla ci sono dei float (che quindi definisce la posizione delle barre), allora facendo un secondo plot, quest’ultimo segue le proprie posizioni.
- Attento pui mettere 2 bar chart, uno con variabili categoriche e uno con float. Le posizioni delle categoriche sono messe automaticamente in integer (che partono quindi da zero). Nell’esempio qui sotto, la barra di nuclear ha posizione sull’asse delle x uguale a 0, hydro e’ in posizione 1, …
- il secondo argomento contiene l’array che con le altezze della barchart
- yerr ??? serve per la barra che indica l’errore, ed e’ un array che deve contenere tanti oggetti quante sono le barre
- width larghezza della barra (altrimenti da’ errore? )
- label non la vedo… scritta forse bisogna attivarla. Anche nel video non fungeva
## energia francese
x = ['nuclear', 'hydro', 'coal', 'gas', 'solar', 'wind', 'other']
per_1 = [71,10,3,7,2,4,3] # percentuale
variance = [8,3,1,3,1,2,1] # varianza per anno
plt.bar(x, per_1, color='purple',yerr=variance, label='prova')
<BarContainer object of 7 artists>
## energia francese
x = ['nuclear', 'hydro', 'coal', 'gas', 'solar', 'wind', 'other']
per_1 = [71,10,3,7,2,4,3] # percentuale
variance = [8,3,1,3,1,2,1] # varianza per anno
plt.bar(x, per_1, color='purple',yerr=variance, label='prova')
y = [el + ' ' for el in x]
z = ['test1', 'test2', 'test3']
z2 = [1, 2, 10]
per_2 = [34,43,21]
plt.bar(z2, per_2, color='red', label='prova')
<BarContainer object of 3 artists>
y
['nuclear ',
'hydro ',
'coal ',
'gas ',
'solar ',
'wind ',
'other ']
Bar Chart affiancate
Qui sotto mettiamo due bar chart affiancate una da parte all’altra. In questo modo possiamo confrontare dati diversi. E’ fondamentale che la posizione dell’array che definisce l’asse delle x della seconda bar chart sia spostato rispetto all’asse delle x della prima bar chart di una quantita’ tale da non fare sovrapporre (a meno di volerlo). Per esempio di puo’ usare lo stesso array maggiorato della larghezza della barchart!
m_eng = (76,85,86,88,93) # percentuale maschi ingegneri
f_eng = (24,15,14,12,7) # femmine
spc = np.arange(5)
larghezza =0.45
plt.bar(spc , m_eng,width=larghezza, label='maschi', edgecolor ='k')
plt.bar(spc+larghezza, f_eng,width=larghezza, label='femmine', edgecolor ='k')
#plt.xticks(spc + larghezza/2, ('Aero', 'Chem', 'Civil', 'Elect', 'Mec'))
plt.xticks(spc , ('Aero', 'Chem', 'Civil', 'Elect', 'Mec')) ; # altrimenti lo mette a meta' strada del primo istogramma
Bar Chart impilate (stacked)
Qui mettiamo le barre una sopra l’altra.
Diamo un’occhiata alla list comprehension che viene usata:
ind = [x for x, _ in enumerate(t_type)]
enumerate
restituisce delle coppie: posizione, oggetto.- Non ci serve l’oggetto ma solo la posizione, qunidi non spreco una variabile y, metto _
- Prendi tutte le posizioni che ci sono nell’oggetto t_type
- questa volta la label e’ apparsa nella legenda.
ATTENTO
- il parametro
bottom
dice cosa c’e’ sotto di questa barchart. In particolare possiamo indicare un array, o anche una somma di array come nell’esempio di cui sotto. Se mettiamo un array che viene disegnato nella barchart, allora stiamo in pratica impilando il nuovo barchart sopra quello dell’altro array
############# DATI ######################
t_type= ['kind', 'elem', 'sec', 'special']
print(type(t_type))
m_teach = np.array([2,20,44,14])
f_teach = np.array([98,80,56,86])
n_teach = np.array([12,14,13,15])
ind = [x for x,_ in enumerate(t_type)] # list comprehension. Vedi sopra per come si legge
plt.bar(ind, n_teach, width=larghezza, label='nuovo', bottom=f_teach+m_teach) # posso metterne piu' di uno sotto
plt.bar(ind, m_teach, width=larghezza, label='maschi', bottom=f_teach) # posso metterne piu' di uno sotto
plt.bar(ind, f_teach, width=larghezza, label='femmine')
plt.legend(loc='lower right'); # non ideale....
#plt.legend(loc=0); # manco questo...
<class 'list'>
Torte - Pie chart, plt.pie()
Vediamo i diagrammi a torta. Per questi si usa il comando:
wedges, texts, autotexts = plt.pie(poke_num, explode=explode, labels=types, colors=colors,
autopct='%1.0f%%', shadow=True,
startangle=140, textprops =dict(color='w'))
Dal punto di vista sintattico la funzione pie()
restituisce 3 oggetti:
- le
wedges
(gli spicchi o cunei del diagramma a torta). - i
texts
- gli
autotext
In questo caso abbiamo prima costruito la figure
, poi gli axes
ed infine abbiamo chiamato la funzione pie
.
E’ un po’ diverso dal solito quando si usava un metodo dell’axes.
-
Nota che in un diagramma a torta, intuitivamente, i valori di larghezza (angolo) associati ad ogni fetta vengono convertiti in percentuali dell’angolo giro. Questo perche’ ci si aspetta che tutti i valori di un array riempiano tutto il cerchio.
-
explode
a questa keyword si deve passare un array di float con tanti ingressi quante sono le fette. Il valore di ogni ingresso dice di quanto viene “estratta” la fetta alla posizione corrispondente, vedi l’esempio sotto. -
nell’esempio sotto ci sono 2 array:
types
epole_num
, questi devono avere il medesimo numero di ingressi. -
labels=types
e’ un parametro che indica le etichette associate ad ogni fetta -
autopct
indica come vengono arrotondati i numeri associati alle larghezze, gli si deve passare come valore una stringa che indica un formato. -
shadow=true
e’ il parametro che dice se mettiamo l’ombra -
colori
ha usato un trucco notevole, ha fatto scrivere dei valori in formato RGB tramite il generatore di numeri casuali. Tre numeri indicano un colore, e lui indicando il range dei colori tra [0, 0.5] ha fatto si’ che vengono scuri. Ha scelto i colori scuri perche’ la scritta viene in bianco! -
Occhio, avevo fatto un errore di sintassi ma non semplice da osservare. Nell’array
types
che contiene dei nomi tra virgolette, in un caso, quando andavo a capo ho dimenticato di mettere una virgola tra un nome e l’altro e lui mi ha preso solo uno dei nomi -
bbox_to_anchor = (1,0,0.5,1)
serve per spostare di 1 e 1/2 a destra della piechart (???)
import random
fig_6 = plt.figure(figsize=(8,5))
axes_6 = fig_6.add_axes([0.1,0.1,0.9,0.9])
#Vogliamo un diagramma a torte
types = ['water', 'normal', 'flying', 'grass', 'psychic','bug',
'fire', 'poison', 'ground','rock','fighting', 'dark', 'steel',
'electric','dragon','fairy','ghost','ice']
poke_num =[133, 109, 101, 98, 85, 77, 68, 66, 65, 60, 57, 54, 53, 51, 50, 50, 46, 40]
colors = []
for i in range(18): # per il testo bianco genero i coloi delle fette in modo che siano scuri
rgb = (random.uniform(0,.5) , random.uniform(0,.5) , random.uniform(0,.5) )
colors.append(rgb)
explode = [0] * 18 # ho creato una lista di 18 zeri (non mi ricordavo questo modo!)
explode[0] = 0.2 # esplodi la prima fetta ma solo di 0.2
#print(len(types));
#print(len(poke_num));
wedges, texts, autotexts = plt.pie(poke_num, explode=explode, labels=types, colors=colors,
autopct='%1.0f%%', shadow=True,
startangle=140, textprops =dict(color='w'))
plt.legend(wedges, types, loc='right', bbox_to_anchor = (1,0,0.5,1)); # sposto dalla piechart
Serie Temporali
Qui vediamo come fare un grafico con una serie temporale in cui i vari punti sono etichettati con un timestamp. Puo’ essere necessario togliere dei giorni particolari e risulta piu’ comodo sapere la data piuttosto che trovare il punto corrispondente della time series.
Il database usato viene da Yahoo riguardo i dati di google, GOOG.csv. (non e’ esattamente come mostrato nel video ma si trova in fretta). Per trovarlo cerca con google “yahoo google stock”, seleziona le date e fai download (nota che la frequenza e’ giornaliera).
All’inizio si carica il file con read_csv
di Pandas, poi si trasforma la tabella in un array di numpy (sono tutti valori numerici). Lui usa un metodo dei DataFrame di Pandas che io non uso mai: tp_numpy()
. Io invece faccio semplicemente np.array()
.
Ho provato a fare un giro piu’ semplice, cercando di plottare i dati direttamwente DAL DataFrame, di cui seleziono le colonne volute (ma avendo prima selezionato le righe, vedi sotto). Sfortunatamente sull’asse delle x vengono dei valori sballati come tics, il grafico e’ pero’ corretto. Questo e’ probabilmente il motivo per cui lui preferisce trasformare tutto in array di Numpy.
Scrubbing data: per esempio vogliamo togliere alcune vacanze, ha controllato due date che sono vacanze e vuole escluderlo.
Usa datetime
. La funzione datetime.datetime(2020,5,25)
crea una data in un oggetto specifico, che puo’ poi essere trasformato a seconda delle esigenze, p.es g/m/a o m/g/a ecc.
Poi costruisce un array di date che vanno da una data iniziale ad una finale, tramite un metodo di pandas: pd.bdate_range
, si puo’ passare il parametro frequency freq ='C'
in questo caso, ma no so cosa sia il valore ‘C’!
holidays
e’ il nome di un altro parametro che appunto corrisponde alle vacanze e possiamo passare un array/tupla contentente dei dati in formato datetime
che vengono riconosciuti. ATTENTO la mia versione non riconosce questo parametro. Ho riscritto tutto e ora funge.
Problema: non so quando ha preso lui le date da Yahoo, io ho piu’ giorni.
Problema2 se uso tutti questi giorni, i tics che vengono segnati sono troppi e sotto l’asse viene un guazzabuglio di linee. Devo modificare per ottenere le date corrette.
import datetime
goog_data = pd.read_csv('GOOG.csv') # IMPORTO il file GOOG.csv che ho salvato nella dir corrente
goog_data_np = goog_data.to_numpy() # trasformo in np.array
#goog_data_np =np.array(goog_data) # modo alternativo di trasformare
goog_cp = goog_data_np[:,4]
holidays = [datetime.datetime(2020,5,25) , datetime.datetime(2020,8,19) ] # creo una lista con due date che saranno vacanze
date_arr = pd.bdate_range(start ='5/20/2020' ,
end ='8/19/2020' ,
freq ='C',
holidays = holidays)
date_arr_np = date_arr.to_numpy()
goog_data.head(3)
Date | Open | High | Low | Close | Adj Close | Volume | |
---|---|---|---|---|---|---|---|
0 | 2019-08-21 | 1193.150024 | 1199.000000 | 1187.430054 | 1191.250000 | 1191.250000 | 740700 |
1 | 2019-08-22 | 1194.069946 | 1198.011963 | 1178.579956 | 1189.530029 | 1189.530029 | 947500 |
2 | 2019-08-23 | 1181.989990 | 1194.079956 | 1147.750000 | 1151.290039 | 1151.290039 | 1687000 |
Selezionare righe secondo delle date
Seguo questo esempio per selezionare le date: https://stackoverflow.com/questions/29370057/select-dataframe-rows-between-two-dates
Creo una mask per selezionare le date che voglio e che devono seguire quelle indicate nel bdate_range
.
In pratica creo una maschera, ovvero un array di bool che poi posso passare a loc!
In questo modo solo gli ingressi in cui la maschera e’ vera vengono selezionati.
- Problema I: devo paragonare delle date… in formati magari diversi
- Soluzione I uso
pd.to_datetime()
che e’ una goduriosa funzione di Pandas che converte una stringa in un oggetto di tipodatetime
. Questo oggetto e’ una data ed e’ possibile paragonare due datetime per vedere chi viene prima o dopo! Questa funzione e’ particolarmente VANTAGGIOSA in quanto riconosce tanti tipi diversi di formato in cui possiamo scrivere una data e li converte i un unico oggetto! - Alternativa usa
parse_dates
(vedi il Finance Module)
Una volta ottenuto un modo per paragonare le date posso creare una lista con valori booleani
in cui seleziono le date (basta un loop), chiamo questo oggetto maschera
- Problema II la maschera cosi’ creata non e’ un oggetto iterabile che si possa mettere nel metodo
loc
di pandas. Devo tasformarlo in un oggetto non iterabile - Soluzione II basta costruire una funzione che prende come input qualcosa e quando lo sputa in output gli metto un
tuple
davanti! - DUBBIO ehi ma nel codice non ho usato la tupla, anzi se dove faccio finanza metto la tupla mi da errore, sembra che una Series di pandas vada bene
Attenzione pero’ la maschera cosi’ creata e’ un oggetto mutabile e questo non puo’ essere usato come ingresso della funzione loc (di PANDAS) perche’ questa necessita oggetti immutabili da cui puo’ estrarre una hashtable.
link utili:
loc: https://stackoverflow.com/questions/29370057/select-dataframe-rows-between-two-dates
to_datetime: https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.to_datetime.html
convertire lista in tupla: https://www.geeksforgeeks.org/python-convert-a-list-into-a-tuple/
# PROBLEMA I
# qui sotto prendo la colonna Date del dataFrame
# poi converto i valori ivi contenuti in un oggetto di tipo datetime con to_datetime
# a questo punto li paragono ai valori entro cui voglio che siano le date, sempre
# sfruttando la funzione di pandas pd.to_datetime
mask = ( ( pd.to_datetime(goog_data['Date']) >= pd.to_datetime('5/20/2020'))
& ( pd.to_datetime(goog_data['Date']) <= pd.to_datetime('8/19/2020')) )
# PROBLEMA II
# l'oggetto mask non e' di tipo immutabile e quindi non puo' essere usato come iteratore
# devo trasformarlo in unoggetto immutabile
def convert(list):
return tuple(list)
mask_t= convert(mask)
#print(type(mask_t) , 'tipo maschera') # controllo
#print(len(goog_data.loc[mask])) # controllo che i due oggetti abbiano lo stesso numero di righe
new = goog_data.loc[mask] # loc NON lavora inplace <===================
new_np = new.to_numpy()
goog_cp = new_np[:,4] #
# PROBLEMA III
# Costruisco un array con le date corrispondenti in modo che io possa poi disegnarle
fig_7 = plt.figure(figsize=(8,5)) # creiamo la figura/canvas come al solito
axes_7 = fig_7.add_axes([0.1,0.1, 0.9, 0.9]) # il grafico non copre tutta la figura, lasciamo un po' di padding
plt.plot(date_arr_np, goog_cp);
#plt.plot(new.Date, new.Close) # questo fa vedere sbagliato i tics sotto
Tabelle
Questo non e’ cosi’ interessante, la cosa che trovo piu’ utile e’ come girare le date sull’asse delle x. Copio il pezzo di notebook scritto da Banas qui sotto:
# Format column data to 2 decimals
goog_data['Open'] = pd.Series([round(val, 2) for val in goog_data['Open']],
index = goog_data.index)
goog_data['High'] = pd.Series([round(val, 2) for val in goog_data['High']],
index = goog_data.index)
goog_data['Low'] = pd.Series([round(val, 2) for val in goog_data['Low']],
index = goog_data.index)
goog_data['Close'] = pd.Series([round(val, 2) for val in goog_data['Close']],
index = goog_data.index)
goog_data['Adj Close'] = pd.Series([round(val, 2) for val in goog_data['Adj Close']],
index = goog_data.index)
# Get most recent last 5 days of stock data
stk_data = goog_data[-5:]
stk_data
# Define headers
col_head = ('Date','Open','High','Low','Close','Adj Close','Volume')
stk_data_np = stk_data.to_numpy()
stk_data_np
# Add padding around cells in table
plt.figure(linewidth=2, tight_layout={'pad':.5}, figsize=(5,3))
# Get rid of axes and plot box
axes_8 = plt.gca()
axes_8.get_xaxis().set_visible(False)
axes_8.get_yaxis().set_visible(False)
plt.box(on=None)
# np.full returns an array filled with 0.1
# cm is a colormap object we are using to use a default blue color
# matplotlib.org/3.1.0/tutorials/colors/colormaps.html
ccolors = plt.cm.Blues(np.full(len(col_head), 0.2))
# Receives data, loc, list of column headers, column header color as array of colors
# You can also add rowLabel, rowColours, rowLoc: Text alignment
the_table = plt.table(cellText=stk_data_np, loc='center', colLabels=col_head,
colColours=ccolors)
# Set table font size
the_table.set_fontsize(14)
the_table.scale(3, 2.5)
C:\ProgramData\Anaconda3\lib\site-packages\IPython\core\pylabtools.py:132: UserWarning: Tight layout not applied. The left and right margins cannot be made large enough to accommodate all axes decorations.
fig.canvas.print_figure(bytes_io, **kw)
ScatterPlot
Qui ci sono dei dati relativi al Coronavirus. E’ importante che ci sia uniformita’ di grandezza per quanto riguarda gli array che vanno plottati:
- ci sono 26 nazioni
- ci sono 26 tassi di mortalita’
- ci sono 26 valori di casi confermati giornalieri
- ci sono 26 dimensioni dei punti
Nota che i questo caso non costruisco la figura e poi gli assi. Questo perche’ viene fatto automaticamente dal comando plt.scatter
. Ci sono 2 vie per ottenere lo stesso grafico:
- costruisco la fig, e gli assi e uso scatter come metodo sull’asse creato
- uso plt.scatter e lui automaticamente crea gli assi!
Argomenti dello scatterplot:
- prima si mettono i valori dell’asse delle x (e’ un
np.array
) - poi l’array per i valori dell’asse delle y (anche questo un
np.array
lungo quanto quello sopra) - s per size (dei punti): NON e’ come gnuplot che accettava le abbreviazioni, qui il parametro si chiama SOLO s!
- c per color (dei punti)
- alpha e’ in pratica il livello di trasparenza, in questo caso e’ fondamentale in quanto alcuni punti andranno a sovrapporsi
# Numpy array con i nomi delle nazioni
cnt_arr = np.array(['Australia','Brazil','Canada','Chile','France','Germany','Greece',
'Iceland','India','Iran','Italy','Mexico','New Zealand','Nigeria',
'Norway','Pakistan','Peru','Russia','Saudi Arabia','Singapore',
'South Africa','Spain','Sweden','Turkey','UK','US'])
# Tasso mortalita per 100k casi Coronavirus
dr_arr = np.array([1.8,53,24.5,56.5,45.4,11.2,2.2,
2.8,4,24.6,58.6,46.3,.5,.5,
4.9,2.9,83.3,11,10.4,.5,
21.5,61.6,56.9,7.3,62.4,52.9])
# Numero giornaliero di casi confermati (Tests)
test_arr = np.array([110,7197,600,1862,1636,1103,35,
10,295,1658,1226,2490,8,243,
48,1395,1101,4447,1443,280,
2830,1602,447,1205,1546,24988])
# Dimensione del punto dei casi confermati
cc_arr = np.array([24236,3456652,125408,390037,256534,229706,7684,
2035,2836925,350279,255278,537031,1654,50488,
10162,290445,549321,935066,302686,56031,
596060,370867,85411,253108,323008,5529824])
cc_arr_sm = cc_arr/1000 # rimpicciolisce a dimensione dei punti (?)
color_arr= np.random.rand(26)
# Se faccio questi sotto vengono aggiunti ad una figura aggiuntiva, non al mio scatterplot
# questo perche' ho provato ad usare la strada per cui prima faccio la figura, aggiungo gli assi
# e il disegno viene con un metodo!
#plt.title('Mortalita per 100k vs. Casi confermati')
#plt.xlabel('Mortalita per 100k')
#plt.ylabel('Casi confermati')
#plt.scatter(dr_arr, test_arr, s=cc_arr_sm, c=color_arr,alpha=0.5 )
#plt.figure(figsize=(8,5))
fig_13 = plt.figure(figsize=(8,5))
axes_13 = fig_13.add_axes([0.1,0.1,0.9,0.9])
axes_13.set_xlabel('Mortalita per 100k')
axes_13.set_ylabel('Casi confermati')
axes_13.set_title('Mortalita per 100k vs. Casi confermati')
axes_13.scatter(dr_arr, # valori sull'asse delle x
test_arr, # valori sull'asse delle y
s=cc_arr_sm, # valori che indicano la dimensione dei punti
c=color_arr, # colori di ogni punto
alpha=0.2 ); # trasparenza 1 = no trasparenza, 0 = completamente trasparente
3D
from mpl_toolkits import mplot3d
abbiamo bisogno di importare questo moduloprojection='3d'
quando si costruisce la figura si aggiunge questo parametrofig_9 = plt.figure(figsize=(8,5), dpi=100)
dpi=100 stranamente sembra avere un effetto sulla dimensione della figura, mentre sembra non prendere il parametro figsize! Probabilmente questo e’ dovuto al fatto che con%matplotlib inline
mi mette le figure come dei png, cambiando il numero di punti questo cambia la dimensione dell’immagine a schermo. Per esempio dpi=100 e’ circa un terzo della figura con dpi=300scatter3D
la funzione per uno scatterplot 3Dc= z_3
se uso questo parametro per i colori, allora quelli piu’ in alto (asse z) avranno una sfumatura differente da quelli in basso
Scatter3D
from mpl_toolkits import mplot3d
fig_9 = plt.figure(figsize=(6,5), dpi=100)
axes_9 = fig_9.add_axes([0.1,0.1,0.9,0.9], projection='3d') # mette degli assi 3D
z_3 = 40 *np.random.random(100) # random: sample dalla [0,1) uniforme
x_3 = np.sin(z_3) * np.random.randn(100) # randn
y_3 = np.cos(z_3) * np.random.randn(100) # randn: sample dalla N(0,1)
#axes_9.scatter3D(x_3,y_3,z_3, cmap='Blues');
axes_9.scatter3D(x_3,y_3,z_3, c=z_3, cmap='Blues');
Contour3D
In questo caso ho bisogno di una funzione z =z(x,y)
questo perche’ lui deve poter sapere la altezza in ogni punto.
-
per costruire una griglia rettangolare devo usare
np.meshgrid
:x_4, y_4 = np.meshgrid(x_4, y_4)
occhio che se non metto questo comando mi dice che c’e’ un errore!? Il motivo e’ semplice. meshgrid prende in ingresso due array 1 dimensionali e restituisce due array 2 dimensionali. In pratica ha fatto un prodotto cartesizano per ognuno dei punti del primo array creando una coppia con quelli del secondo array (e viceversa per il secondo array). Questo perche’ contour3D si aspetta delle matrici per le x e le y e anche le z, in quanto per ogni x e y c’e’uno z. Per capire meglio fai fare print(x_4) prima e dopo meshgrid e vedi la differenza. - Angolo di vista, per cambiare:
axes_9.view_init(45, 55)
. questo sposta l’angolo di vista di 45 gradi e lo ruota di 55 - il 4to parametro indica il numero di linee. In pratica quante fette parallele al piano xy che vengono visualizzate, se metto 80 sono tante, se metto 20 sono poche
fig_9 = plt.figure(figsize=(6,5), dpi=100)
axes_9 = fig_9.add_axes([0.1,0.1,0.9,0.9], projection='3d')
def get_z (x,y):
return np.sin(np.sqrt(x**2+y**2))
x_4 = np.linspace(-6,6,30)
y_4 = np.linspace(-6,6,30)
#print(x_4)
x_4, y_4 = np.meshgrid(x_4, y_4)
#print(x_4)
z_4 = get_z(x_4, y_4)
axes_9.set_xlabel('x')
axes_9.set_ylabel('y')
axes_9.set_zlabel('z')
axes_9.view_init(35, 30) # angolo di visione, angolo di rotazione
axes_9.contour3D(x_4,y_4,z_4, 20, cmap='Blues');
WireFrame e surface
In questo caso vengono connessi tutti i punti da un segmento.
-plot_wireframe(x_4,y_4,z_4, cmap='Blues')
in questo caso non devo passare il numero di tagli paralleli all’asse xy, quindi non ha il 4to parametro.
edgecolor ='none'
non colora i segmenti di collegamento (il wireframe)
fig_9 = plt.figure(figsize=(6,5), dpi=100)
axes_9 = fig_9.add_axes([0.1,0.1,0.9,0.9], projection='3d')
axes_9.view_init(35, 30) # angolo di visione, angolo di rotazione
#axes_9.plot_wireframe(x_4,y_4,z_4, cmap='Blues');
axes_9.plot_surface(x_4,y_4,z_4, rstride=1, cstride=1, cmap='Blues', edgecolor='r');
Finance Module
per installare ho fatto:
- anaconda prompt
- pip install mpl_finance
- pip install –upgrade mplfinance # upgrade
questo modulo fa vedere le candele giapponesi ecc.
- posso cambiare il nome dell’index:
goog_df.index.name='Date'
a questo punto l’index non si chiama piu’ index ma Date! mi pare di capire che questo sia necessario perche’ la libreria prenda correttamente il dataframe.
Candele giapponesi
- Attento se prendi tante date, non riesci a vedere le candele! devono essere poche per essere visibili.
trendlines
possiamo mettere automaticamente delle medie mobili con il parametro:
-type='ohlc', mav=4
# che significa che mette Open High Low Close e la media mobile basata sui precedenti 4 punti,nota che possiamo tenere come type ‘candle’ (ma si vede meno bene)
- altri tipi di medie mobili.
mav=(3,5,7)
e’ bene usare dispari, quindi fa vedere 3 medie mobili basate sui 3, 5 e 7 gg precedenti - il parametro
volume=True
va vedere i volumi giornalieri - mostrare non-tading days:
show_nontrading=True
parse_dates
parse_dates=true
vuol dire che non prende le date come delle semplici stringhe ma le legge come date, infatti ora sono in formato Timestamp
import mplfinance as mpf
goog_df = pd.read_csv('GOOG.csv', index_col = 0, parse_dates=True)
#type(goog_df.index[0])
goog_df.index.name='Date'
#goog_df = pd.read_csv('GOOG.csv')
goog_df.head(3)
Open | High | Low | Close | Adj Close | Volume | |
---|---|---|---|---|---|---|
Date | ||||||
2019-08-21 | 1193.150024 | 1199.000000 | 1187.430054 | 1191.250000 | 1191.250000 | 740700 |
2019-08-22 | 1194.069946 | 1198.011963 | 1178.579956 | 1189.530029 | 1189.530029 | 947500 |
2019-08-23 | 1181.989990 | 1194.079956 | 1147.750000 | 1151.290039 | 1151.290039 | 1687000 |
mask = ( ( pd.to_datetime(goog_df.index) >= pd.to_datetime('5/20/2020'))
& ( pd.to_datetime(goog_df.index) <= pd.to_datetime('8/19/2020')) )
new = goog_df.loc[mask] #
#mpf.plot(new, type='line') # normali linee
#mpf.plot(new, type='candle') # candele giapponesi
#mpf.plot(new, type='ohlc', mav=4) # open high low close + moving average
mpf.plot(new, type='ohlc', mav=(3,5,7), volume=True, show_nontrading=True) # open high low close + moving average
Heatmap
ho un array 2 dimensionale e voglio mostrarlo con dei colori invece che dei numeri.
symptoms
sono i 4 tipi di malattia a cui si riferiscono i dati (dyspnea = short of breath)dates sono
i giorni in cui sono state fatte le osservazioni (sono 9 giorni)symp_per
sono il numero di pazienti per giorno per malattia e’ un array 4x9
Nota: pensavo che la heatmap di default mettesse delle righe bianche in mezzo alle caselle risultando molto poco chiara! in realta’ e’ una delle opzioni lasciate dal finance module!!!! (se faccio girare prima la casella sotto le righe bianche in mezzo non ci sono!)
- Per la heatmap si deve usare
subplots()
(non figure) - Cosa fa il comando? prende la matrice che ha 0,3 righe, e 0,8 colonne. Per ognuna delle righe e delle colonne scrive un colore associato al numero dell’ingresso dell’array da disegnare.
symptoms = ["Coronavirus","Influenza","Pneumonia","Dyspnea"]
dates = ["Jun28","Jul05","Jul12","Jul19","Jul26","Aug02","Aug09","Aug16","Aug21"]
symp_per = np.array([[5.2, 5.5, 5.7, 5.6, 5.3, 5.1, 5.0, 4.9, 5.3],
[3.5, 4.0, 4.3, 3.9, 3.5, 3.2, 2.7, 2.2, 2.0],
[1.8, 2.2, 2.3, 2.2, 2.1, 1.9, 1.7, 1.4, 1.3],
[1.0, 1.1, 1.1, 1.0, 0.9, 0.8, 0.8, 0.8, 0.7]])
fig_10 , axes_10 = plt.subplots()
im= axes_10.imshow(symp_per, cmap='Wistia')
tics
non chiaro perche’ all’inizio metta un np.arange, dato che abbiamo gia’ un array con dates e symptoms:
- ok:
axes_10.set_xtics(np.arange(len(dates))
qui definisce la distanza (posizione) che devono avere i tics sulla mappa. axes_10.set_xticlabels(dates)
questo definisce cosa ci deve essere nei ticks- occhio che ticks ha la k
- occhio i ticks vanno assegnati DOPO avere definito la figura e l’axes
- giro i ticks di 45 gradi!
plt.setp(axes_10.get_xticklabels(), rotation=45, ha='right', rotation_mode='anchor')
(non chiaro l’anchor cosa faccia)
fig_10 , axes_10 = plt.subplots()
im= axes_10.imshow(symp_per, cmap='Wistia')
axes_10.set_xticks(np.arange(len(dates))) # posizione tics sull'asse x
axes_10.set_yticks(np.arange(len(symptoms))) # posizione tics sull'asse y
axes_10.set_xticklabels(dates) # cosa viene mostrato ad ogni tic dell'asse x
axes_10.set_yticklabels(symptoms) # cosa viene mostrato ad ogni tic dell'asse x
plt.setp(axes_10.get_xticklabels(), rotation=45, ha='right');
Numeri nelle caselle
metto qui anche i numeri dentro le caselle. Nota che usa un costrutto che non ho mai usato prima, chiama un metodo dell’axes dentro una funzione di matplotlib.
-plt.setp(axes_10.get_xticklabels(), rotation=45, ha='right');
- chiama
fig_10 , axes_10 = plt.subplots()
im= axes_10.imshow(symp_per, cmap='Wistia')
axes_10.set_xticks(np.arange(len(dates))) # posizione tics sull'asse x
axes_10.set_yticks(np.arange(len(symptoms))) # posizione tics sull'asse y
axes_10.set_xticklabels(dates) # cosa viene mostrato ad ogni tic dell'asse x
axes_10.set_yticklabels(symptoms) # cosa viene mostrato ad ogni tic dell'asse x
plt.setp(axes_10.get_xticklabels(), rotation=45, ha='right');
for i in range(len(symptoms)):
for j in range(len(dates)):
text = axes_10.text(j,i, symp_per[i,j], ha='center', va='center', color='k', fontweight='bold')
Riempire le aree tra curve
ci sono ottimi esempi al sito di matplotlib:
https://matplotlib.org/3.1.1/gallery/lines_bars_and_markers/fill_between_demo.html
il metodo degli assi fill_between()
permette di riempire quello che c’e’ tra una curva e l’altra.
x = np.arange(0.0, 2, 0.01) # le x
y1 = np.sin(2 * np.pi * x) # y1 = la funzione seno
y2 = 1.2 * np.sin(4 * np.pi * x) # y2 = funzione seno piu' larga e con maggiore frequenza
fig, (ax1, ax2, ax3) = plt.subplots(3, 1, sharex=True)
ax1.fill_between(x, 0, y1) # riempie tra 0 e y1
ax1.set_ylabel('TRA y1 e 0')
ax2.fill_between(x, y1, 1) # riempie tra y1 e 1 (quello che c'e' sopra y1)
ax2.set_ylabel('TRA y1 e 1')
ax3.fill_between(x, y1, y2) # quello che c'e' TRA y1 e sotto y2
ax3.set_ylabel('TRA y1 e y2')
ax3.set_xlabel('x')
Text(0.5, 0, 'x')
si possono mettere ulteriori condizioni per dare dei colori diversi tra le curve. In particolare si aggiungono dei parametri logici.
fig, (ax, ax1) = plt.subplots(2, 1, sharex=True) # costruisce subplots
ax.plot(x, y1, x, y2, color='black') # disegna le 2 funzioni
ax.fill_between(x, y1, y2, where=y2 >= y1, facecolor='green', interpolate=True)
ax.fill_between(x, y1, y2, where=y2 <= y1, facecolor='red', interpolate=True)
ax.set_title('fill between where')
# Test support for masked arrays.
y2 = np.ma.masked_greater(y2, 1.0)
ax1.plot(x, y1, x, y2, color='black')
ax1.fill_between(x, y1, y2, where=y2 >= y1,
facecolor='green', interpolate=True)
ax1.fill_between(x, y1, y2, where=y2 <= y1,
facecolor='red', interpolate=True)
ax1.set_title('Now regions with y2>1 are masked')
Text(0.5, 1.0, 'Now regions with y2>1 are masked')
Ticks
Al comando ticks possono essere passati degli argomenti per specificare:
rotation = 45
ruota di 45 gradi- se il primo ingresso e’ un np.array allora quelli sono i ticks (le posizioni)
- se il secondo ingresso e’ una tupla, allora alle varie posizioni dei ticks vengono messi i valori della tupla
fontsize=24
viene passato
come al solito puoi passare piu’ di un parametro basta che sia separato dalla virgola!
plt.plot(x_1,y_1)
#plt.xticks(np.linspace(0,5,100))
#plt.xticks(np.arange(15))
#plt.xticks(np.arange(5), ('Tom', 'Dick', 'Harry', 'Sally', 'Sue'))
#plt.grid(False, color='r', dashes=(0,2,1,2))
plt.grid(False)
#plt.grid(b=None)
degrees = 45
plt.xticks(rotation=degrees) # Rotazione dei ticks
mioArray= np.array([1,2,3,4,8])
#plt.xticks(np.linspace(0,5,5), ('Tom', 'Dick', 'Harry', 'Sally', 'Sue'))
plt.grid(True) # presenza della grid
plt.xticks(fontsize=24) # GRANDEZZA FONT
plt.xticks(mioArray, ('Gino', 'Pino', 'Mino', 'Tino', 'Asdrubale'));
Animazioni
Testo di riferimento: https://riptutorial.com/Download/matplotlib-it.pdf
Lo ho scaricato ed e’ nella dir.
- Bisogna importare anche la parte del package che fa animazioni.
- Bisogna usare il metodo
set_data()
che assegna i valori delle x e y di un grafico
%matplotlib notebook
import matplotlib.animation as animation
TWOPI = 2*np.pi
fig, ax = plt.subplots() # costruiamo una figura e un array di assi
t = np.arange(0.0, TWOPI, 0.001) # t =array di posizioni
s = np.sin(t) # y = sin(t)
l = plt.plot(t, s) # grafico
ax = plt.axis([0,TWOPI,-1,1]) # assi
redDot, = plt.plot([0], [np.sin(0)], 'ro') # l'oggetto "redDot" disegna il punto rosso, all'inizio e' in zero
def animate(i): # questa funzione modifica i parametri del punto rosso
redDot.set_data(i, np.sin(i)) # quindi il resto del grafico resta invariato!
return redDot,
# create animation using the animate() function
myAnimation = animation.FuncAnimation(fig, animate, frames=np.arange(0.0, TWOPI, 0.01), \
interval=1, blit=True, repeat=True)
<IPython.core.display.Javascript object>
Mio test di animazione
vorrei fare estendere la funzione seno, in modo che ad ogni frame sia moltiplicata per una diversa ampiezza. Attenzione: ho provato a farlo girare molte volte e non andava. Ho resettato il kernel e ora sembra fungere. Mi viene il dubbio che il problema fosse connesso a qualche cella che avevo lasciato attiva.
- Curiosamente se metto i limiti degli assi il grafico non appare! Errore Ax e’ un array di assi!
interval=1
rallenta l’esecuzione del programma- frames sono tutti i vari prarametri che andranno a definire i frame
possiamo ingrandire o diminuire la dimensione dei limiti: https://stackoverflow.com/questions/53423868/matplotlib-animation-how-to-dynamically-extend-x-limits
TWOPI = 2*np.pi
#fig, ax = plt.subplots() # costruiamo una figura e un array di assi
fig = plt.figure()
ax = fig.add_subplot(111, autoscale_on=False, xlim=(0, 6.29), ylim=(-2, 2))
#ax = plt.axis([0,TWOPI,-1,1]) # ATTENTO assi QUESTO BLOCCA set_xlim
#ax.set_xlim([0,TWOPI]) # ERRORE ax non e' un asse ma una tupla di assi!
#ax.set_ylim([-1,1]) # ERRORE
t = np.arange(0.0, TWOPI, 0.001) # t =array di posizioni
s = np.sin(t)
# y = sin(t)
plt.grid(False)
new = plt.plot(t, t) # bisettrice
second = plt.plot(t,s/2)
curva, = plt.plot(t, s) # grafico
#ax = plt.axes(xlim=(0, 10), ylim=(-1, 1))
def animate(A): # questa funzione modifica i parametri del punto rosso
curva.set_ydata(A *np.sin(t)) # quindi il resto del grafico resta invariato!
#print(A*np.sin(t))
return curva,
frames1 = np.arange(0.0,1.0,0.001)
frames2 = np.arange(1.0,0.0,-0.001)
frames = np.concatenate((frames1, frames2), axis=None)
# create animation using the animate() function
#myAnimation = animation.FuncAnimation(fig, animate, frames = np.arange(0.0, 1.0, 0.001), \
# interval=10, blit=True, repeat=True)
myAnimation = animation.FuncAnimation(fig, animate, frames = frames, \
interval=1, blit=True, repeat=True)
<IPython.core.display.Javascript object>
Slider interattivo
possiamo modificare la figura tramite uno slider interattivo! In questo caso non uso la funzione animate, perche’ la modifica viene fatta in base a cosa tocco sullo slider.
from matplotlib.widgets import Slider
TWOPI = 2*np.pi
fig, ax = plt.subplots()
A0 = .5 # valore iniziale ampiezza
t = np.arange(0.0, TWOPI, 0.001) # x del grafico
s = A0*np.sin(t) # y del grafico (iniziale)
l, = plt.plot(t, s, lw=2) # grafico (da capire la virgola)
ax = plt.axis([0,TWOPI,-1,1]) # assi (che non verranno toccate) ???
axamp = plt.axes([0.25, .03, 0.50, 0.02]) # non chiaro axIs e axEs
# Slider
samp = Slider(axamp, 'Amp', 0, 1, valinit=A0) # SLIDER interattivo, si chiama "samp"
def update(val):
# amp is the current value of the slider
amp = samp.val # valore corrente dello slider
# update curve
l.set_ydata(amp*np.sin(t)) # fai update delle y della curva
# redraw canvas while idle
fig.canvas.draw_idle()
samp.on_changed(update) # ridisegna la figura se muoviamo lo slider
#plt.show()
<IPython.core.display.Javascript object>
0
Foto
Vediamo come mostrare una immagine. Si passa un array 2D e questo viene convertito automaticamente, assegnando ai valori un colore. Per esempio:
immagine = np.array([ [1,0,0,0,1,0,0,0,1],
[0,0,0,0,1,0,0,0,0],
[0,0,0,0,1,0,0,0,0],
[0,0,0,0,1,0,0,0,0],
[0,0,0,0,1,0,0,0,0],
[1,0,0,0,1,0,0,0,1]])
plt.imshow(immagine)
<matplotlib.image.AxesImage at 0x2de6a38e640>
Unpacking
questo non e’ strettamente connesso con matplotlib….
numbers = [1, 2, 3, 4, 5, 6]
first, *rest = numbers # multiple assignment
print(rest)
print(first)
d = dict(a=5,b=2,c=4)
[2, 3, 4, 5, 6]
1
enumerate()
for o,_ in enumerate(d):
print(o) # stampa l'ordine degli oggetti
0
1
2
for _, o in enumerate(d):
print(o) # stampa le chiavi del dizionario
a
b
c
for _, o in enumerate(d):
print(d[o]) # stampa i valori del dizionario
5
2
4
for o in enumerate(d):
print(o) # stampa le NUOVE coppie chiave-chiave vecchia costruite da enumerate()
(0, 'a')
(1, 'b')
(2, 'c')
Comments