Matplotlib este o bibiloteca care permite generarea si afisarea unor obiecte grafice 2D si 3D. Modulul matplotlib.pyplot contine functii ce genereaza grafice de functii, vizualizeaza multimi de puncte, matrici ca imagini, bare, histograme, etc.
Pentru a afisa in IPython Notebook figurile generate prin rularea unei celule cod se da comanda magica:
In [1]:
%matplotlib inline
Apoi se importa modulul astfel:
In [2]:
import matplotlib.pyplot as plt
Orice functie din acest modul se apeleaza apoi ca plt.NumeFunctie.
Pe WEB gasiti numeroase exemple in care nu se importa matplotlib.pyplot, ci pylab,
care este un modul ce combina functionalitatea modulelor matplotlib.pyplot si numpy
intr-un singur namespace (este preferat de utilizatorii din domenii externe CS).
Pentru a genera graficul unei functii $f:[a,b]\to\mathbb{R}$ se procedeaza teoretic astfel:
se divizeaza intervalul $[a,b]$ in n intervale egale, cu pasul $h=(b-a)/n$.
Se evalueaza functia $f$ in punctele de diviziune $x_i=a+i*h$ ale intervalului $[a,b]$, si se noteaza $y_i=f(x_i)$, $i=\overline{0,n}$,
Graficul discretizat este reprezentat de punctele de coordonate $(x_i,y_i)$, $i=\overline{0,n}$.
functia plt.plot(x,y) avand ca argumente fie listele x,y de elemente $x_i$, respectiv $y_i$, fie array-urile 1D (vectorii) de elemente $x_i$,
respectiv $y_i$, interpoleaza liniar punctele $(x_i,y_i)$ (uneste doua puncte consecutive printr-un segment), genereaza graficul si il afiseaza.
Pentru a genera graficul functiei $f(x)=e^{-x/8}\cos x$, pentru $x\in[0, 6\pi]$, divizam intervalul $[0,6\pi]$ prin $n=300$ puncte astfel:
In [3]:
import numpy as np
a=0
b=6*np.pi
n=300
x=np.linspace(a, b,n)
y=np.exp(-x/8)*np.cos(x)
plt.plot(x,y, 'r')
plt.title('Grafic de functie')
plt.xlabel('x')
plt.ylabel('y=f(x)')
Out[3]:
O alta solutie este sa divizam intervalul $[a,b]$ precizand pasul de diviziune, h, nu numarul de puncte de diviziune:
In [4]:
a=-5
b=7
h=0.01
X=np.arange(a,b, h)
Y=-2*X*X+X+1
plt.plot(X,Y, 'g')
plt.title('Un arc de parabola')
Out[4]:
Daca pasul de diviziune al intervalului nu este suficient de mic graficul unei functii derivabile nu este afisat neted, ci "cu colturi", deoarece
functia plt.plot interpoleaza liniar doua puncte consecutive $(x_i, y_i)$, $(x_{i+1}, y_{i+1})$, adica traseaza segmentul care le uneste:
In [5]:
a=0
b=2*np.pi
h=0.5
xx=np.arange(a, b, h)
yy=np.sin(xx)
plt.plot(xx, yy)
Out[5]:
Pe langa trasarea unor grafice, functia plt.plot poate realiza vizualizarea unui nor de puncte
plasand cate un marker in pozitiile punctelor din nor.
Markere-le uzuale sunt 'o', '*', '.', 'x'. Ele pot fi inserate dupa codul culorii astfel:
In [6]:
x=np.random.random((1,10))
y=np.random.random((1,10))
plt.plot(x,y, 'b*')
Out[6]:
Apelul functiei matplotlib.pyplot.plot se realizeaza fie transmitandu-i doar argumente obligatorii, fie argumente si cuvinte cheie carora li s-au atribuit valori.
Atunci cand am prezentat sintaxa unei functii in Python am precizat doar ca o functie poate avea un numar de parametri, fara a intra in detalii relativ la natura argumentelor ce se transmit la apelul functiei.
Functia plt.plot este un exemplu de functie care ilustreaza concret diferitele posibilitati.
O functie in Python poate fi apelata, cu urmatoarele tipuri de argumente:
argumente obligatorii in numar fix sau variabil
argumente cuvinte cheie
Argumentele obligatorii sunt transmise unei functii in pozitie si ordine precisa.
De exemplu pentru functia plt.plot listele (sau array-urile 1D) x, y, de aceeasi lungime $n$, continand respectiv abscisele si ordonatele unor puncte, sunt argumente ce se transmit in aceasta ordine pentru a trasa graficul unei functii $y=f(x)$ sau pentru a marca punctele de coordonate $(x_i, y_i)$, $i=0, 1,\ldots, n-1$.
In locul primelor doua argumente, se poate transmite insa doar singur un argument pentru plt.plot si anume o lista (sau un array 1D), y. In acest caz lista absciselor este implicita, ea fiind lista indicilor, $0,1,2, \ldots, len(y)-1$, a elementelor din y:
In [7]:
y=[2,4,1,3,-2,5]
plt.plot(y)
Out[7]:
Pentru a trasa un segment intre doua puncte de coordonate $(2,4)$, $(6,-1)$, constituim lista absciselor,
x=[2,6], si respectiv a ordonatelor celor doua puncte, y=[4,-1]:
In [8]:
x=[2,6]
y=[4,-1]
plt.plot(x,y)
Out[8]:
Un alt argument al functiei plt.plot este culoarea de trasare sau marcare a punctelor.
Implicit culoarea este setata pe blue (a se vedea segmentul de dreapta de mai sus).
Culoarea de trasare/marcare se poate transmite in mai multe moduri:
'b', blue; 'g', green; 'r', red; 'c', cyan; 'm', magenta; 'y', yellow; 'k', black; 'w', white.
folosind cuvantul cheie color setat cu un tuple, color=(r, g, b) sau color=(r,g,b,alpha). Elementele celor 2 tuple-uri sunt subunitare
si r,g,b indica cantitatea de red, green si blue din care este sintetizata culoarea.
alpha indica transparenta culorii. Pentru alpha mai apropiat de 1, culoarea este mai opaca, iar mai apropiat de zero, mai transparenta.
folosind cuvantul cheie color setat cu un string ce reprezinta codul html al unei culori,
color='#33FF99'
In [9]:
x=[2,4,3,1,5,0.7,6]
y=[1,3,2,2.41,2.5, 3.13, 2]
plt.subplot(1,4,1)
plt.plot(x,y, 'o', color=(0.86, 0.10, 0.46))
plt.subplot(1,4,2)
plt.plot(x,y, 'o', color=(0.86, 0.10, 0.46, 0.45))
plt.subplot(1,4,3)
plt.plot(x,y, 'o', color='#33FF99')
plt.subplot(1,4,4)
plt.plot(x,y, color='k')
Out[9]:
In secventa de cod de mai sus apare functia plt.subplot(nrlin,nrcol, nrfig) care indica ca se
vor genera/afisa mai multe figuri, plasate intr-o matrice cu nrlin linii si nrcol coloane.
nrfig indica a cata figura din cele nrlin*nrcol va fi generata.
In exemplul de mai sus se genereaza 4 figuri plasate pe linie.
Inserarea marker-ului 'o' ca argument are ca efect afisarea unui cerc colorat in pozitia de coordonate $(x(i), y(i))$. Indicand un marker pentru puncte, punctele consecutive nu sunt unite de segmente. Suprimand marker-ul observam in figura 4 ca punctele sunt interpolate.
Cuvintele cheie sunt argumente optionale pentru o functie, care se transmit sub forma
cuvantCheie=valoare. Argumentele cuvinte cheie se insereaza dupa argumentele pozitionale (cu pozitie fixa).
Dintre cuvintele cheie ce se pot transmite ca argumente functiei plt.plot amintim:
linestyle (tipul liniei ce se traseaza). linestyle sau simplu, ls, se poate seta ca fiind:
solid, dashed, dottedlinewidth (grosimea liniei de trasare) sau scurt, lw, se poate seta cu un numar float ce reprezinta grosimea in puncte.
In [10]:
x=np.arange(0,5, 0.3)
y=x*x/8-x
plt.subplot(1,3,1)
plt.plot(x,y, lw=2, ls='dotted')
plt.subplot(1,3,2)
plt.plot(x,y, lw=3, ls='dashed')
plt.subplot(1,3,3)
plt.plot(x,y, 'r', ls='solid', lw=4)
Out[10]:
Cuvintele cheie se pot plasa in orice pozitie dupa argumentele obligatorii.
In modulul matplotlib.pyplot sunt definite si functii care manipuleaza imagini.
Array-urile 2D pot fi afisate ca imagini. Functiile de baza destinate imaginilor sunt:
plt.imread() incarca o imagine intr-un array
plt.imsave() salveaza un array intr-o imagine
plt.imshow() afiseaza imaginea
In [11]:
import matplotlib
X=np.random.random((16,16))# genereaza o matrice de tip 16x16 de elemente
#aleator generate in intervalul [0,1)
img=plt.imshow(X,cmap=matplotlib.cm.spectral, interpolation='nearest')#afiseaza matricea ca o
#imagine care rezulta realizand o corespondenta intre numerele din intervalul [0,1] si
#un colormap(paleta de culori)
In [12]:
X=plt.imread('Imag/Iony.png')
print 'Imaginea este de tip', X.shape
plt.imshow(X)
Out[12]:
matplotlib contine numeroase alte module care vor fi prezentate pe masura ce vor fi folosite.
Un script Python NumeScript.py care se ruleaza din linia de comanda sau in Spyder si apeleaza functii din matplotlib.pyplot va afisa figura generata doar daca la sfarsitul script-ului se insereaza functia
plt.show(). Altfel figura desi generata, nu este afisata.
Un exemplu de astfel de script este urmatorul:
In [13]:
import numpy as np
import matplotlib.pyplot as plt
t=np.arange(0,4, 0.01)
x=np.exp(-t)*np.cos(2*np.pi*t)
y=np.exp(-t)*np.sin(2*np.pi*t)
plt.plot(x,y,'r')
plt.axis('equal')
plt.xlabel('x(t)')
plt.ylabel('y(t)')
plt.show()
Daca copiati liniile de cod din celula precedenta si le salvati intr-un fisier spirala.py si comentati linia
plt.show() veti vedea ca la rulare nu este afisat nici un mesaj de eroare, dar figura nu este vizualizata.
Decomentand plt.show() va apare figura de mai sus.
In [1]:
from IPython.core.display import HTML
def css_styling():
styles = open("./custom.css", "r").read()
return HTML(styles)
css_styling()
Out[1]: