Le trio Numpy / Scipy / Matplotlib

Introduction aux librairies scientifiques Python

Home python

L’un des intérêts du Python réside dans son approche Batteries Included qui lui confèrent une grande polyvalence. Grace à ses Batteries, le Python peut aussi bien réaliser des calculs mathématiques poussés que gérer un site web ou traiter des images.

Dans les sections suivantes, nous allons faire un tour rapide de plusieurs Batteries particulièrement utiles pour les scientifiques. Plus particulièrement, nous allons nous focaliser sur le trio Numpy/Scipy/ Matplotlib...véritable couteau suisse du calcul scientifique en Python !

Utilisation d’une Battery

Pour inclure une Battery dans un programme, il faut explicitement l’importer en début de programme. Le programme suivant montre comment importer la librairie Numpy et utiliser sa fonction ones (création d’un tableau comportant N éléments à 1)

from numpy import *

x=ones(10) #création d'un tableau de 1
print(x) #affichage du tableau

Pour éviter d’éventuels conflits lors de l’importation des Batteries (doublons sur les noms de fonctions, etc), il est possible de définir le namespace d’une librairie en utilisant le terme as. A titre d’illustration, le programme suivant importe Numpy avec le namespace np

import numpy as np #importation de numpy avec le namespace np

x=np.ones(10) #création d'un tableau de 1
print(x) #affichage du tableau
Numpy

Numpy

Documentation Numpy: https://docs.scipy.org/doc/numpy/reference/routines.html

La librairie Numpy permet la manipulation des tableaux et des matrices. Elle intègre également un grand nombre de fonctionnalités mathématiques. Le programme suivant montre comment utiliser certaines de ses fonctions. Contrairement à Matlab, le premier élément d’un tableau est stocké à la position 0.

from numpy import * #importation de Numpy

mon_tableau=array([0,3,4,19,0,221,3,5]) #création d'un tableau Numpy
print(mon_tableau) #affichage du contenu du tableau

#extraction de quelques informations
taille=len(mon_tableau) #détermine la taille du tableau
premier=mon_tableau[0] #extraction du premier élement
dernier=mon_tableau[-1] #extraction du dernier element (index=-1)
print("taille={}, premier={}, dernier={}" %.format(taille,premier, dernier))

mon_tableau[1]=100 #changement d'un élement
print(mon_tableau)

#recherche de l'element le plus grand
print(amax(mon_tableau)) #valeur maximale
print(argmax(mon_tableau)) #positon de la valeur maximale

#Quelques fonction mathématiques
print(sum(mon_tableau)) #calcul et affichage de la somme
print(mean(mon_tableau)) #calcul et affichage de la moyenne
print(var(mon_tableau)) #calcul et affichage de la variance
print(power(mon_tableau,2)) #calcul et affichage du carré de chaque élement
print(cos(mon_tableau)) #calcul et affichage du cosinus de chaque élement

Généralement, l’utilisation de Numpy permet de réduire considérablement le nombre de boucles dans votre programme. En effet, lorsqu’une fonction mathématique est appliquée à un tableau Numpy, Numpy va automatiquement appliquer cette fonction à chaque élément du tableau.

Pour illustrer cette fonctionnalité, imaginons que nous souhaitons calculer le cosinus de plusieurs angles. Avec un langage de bas niveau comme le C, il faut créer un tableau contenant nos angles puis parcourir ce tableau avec une boucle for. Avec Numpy, c’est plus simple :)

from numpy import * #importation de Numpy

mes_angles=array([0,pi/6,pi/4,pi/3,pi/2,pi]) #création d'un tableau Numpy
mes_cosinus=cos(mes_angles) #la fonction cos est appliquée à l'ensemble des élements du tableau

print(mes_cosinus)

Matplotlib

Documentation Matplotlib: http://matplotlib.org/contents.html

Tout scientifique qui se respecte doit posséder dans sa trousse à outils une librairie d’affichage graphique digne de ce nom pour visualiser ses données. C’est ici que Matplotlib intervient. La librairie Matplotlib permet l’affichage de courbes, de graphiques, d’histogrammes et l’export des courbes dans divers formats (pdf, svg, png ou bmp). Matplotlib possède également un module nommé pylab utilisant une syntaxe proche de Matlab pour l’affichage. L’exemple ci-dessous montre comment générer puis tracer une sinusoîde avec le module pylab.

from numpy import * #import de numpy
from pylab import * #import de matplotlib.pylab

t = arange(0, 1, 1/1000) #creation de la base temps avec numpy
s = sin(2*pi*10*t) #creation d'une sinusoide à 10Hz

plot(t, s) #Affichage via la fonction plot de Matplotlib
xlabel('Temps (s)') #définition de l'axe des abscisses
ylabel('Amplitude') #définition de l'axe des ordonnées
show() #affichage des courbes
Affichage d'une sinusoide

La superposition de deux courbes s’obtient simplement en appelant plusieurs fois la fonction plot. Le programme suivant illustre cette fonctionnalité.

from numpy import * #import de numpy
from pylab import * #import de matplotlib.pylab

t = arange(0, 1, 1/1000) #creation de la base temps avec numpy
s = sin(2*pi*10*t) #creation d'une sinusoide à 10hz
s2 = cos(2*pi*10*t) #creation d'une sinusoide à 10hz

plot(t, s,label="sinus") #Affichage via la fonction plot de Matplotlib
plot(t, s2,label="cosinus")
xlabel('Temps (s)') #définition de l'axe des abscisses
ylabel('Amplitude') #définition de l'axe des ordonnées
legend() #ajout de la légende
show() #affichage des courbes
Superposition de courbes

Scipy

Documentation Scipy: http://docs.scipy.org/doc/scipy/reference

La librairie Scipy intégre un ensemble de modules pour l’optimisation, l’algèbre linéaire, les statistiques, le traitement du signal et le traitement d’images.

Analyse spectrale

L’exemple ci dessous montre comment utiliser Scipy pour calculer le spectre d’une sinusoïde.

from numpy import * #import de numpy
from scipy import signal #import du module signal de scipy
from pylab import * #import de matplotlib.pylab

Fe=100 #fréquence d'échantillonnage
t = arange(0, 0.5, 1/Fe) #creation de la base temps avec numpy
s = sin(2*pi*10*t) #creation d'une sinusoide à 10hz
f,Pxx=signal.periodogram(s,Fe) #calcul du periodogram
f2,Px2=signal.periodogram(s,Fe,None,10*Fe) #calcul du periodogram avec zero padding

plot(f,Pxx,label="periodogramme") #Affichage via la fonction plot de Matplotlib
plot(f2,Px2,label="periodogramme avec zero padding")
xlabel('Frequence (Hz)') #définition de l'axe des abscisses
ylabel('Module') #définition de l'axe des ordonnées
legend()
show() #affichage des courbes
Affichage d'un spectre (avec et sans zero padding)

Génération aléatoire

Scipy dispose également de fonctionnalités puissantes pour la génération de nombres aléatoires. Le programme suivant montre comment générer 1000 nombres aléatoires suivant une loi Gaussienne de moyenne nulle et de variance unitaire.

from numpy import * #import de numpy
from pylab import * #import de matplotlib.pylab
from scipy.stats import norm #import du module norm de scipy.stats

r=norm.rvs(size=1000) #Réalisation aléatoire suivant une loi gaussienne
moyenne=mean(r) #calcul de la moyenne
variance=var(r) #calcul de la variance
print("Moyenne: %f, variance: %f" %(moyenne,variance))

plot(r) #Affichage de la réalisation aléatoire via la fonction plot de Matplotlib
xlabel('Echantillons')
ylabel('Valeur')

figure() #création d'une nouvelle figure
hist(r, histtype='stepfilled') #affichage de l'histogramme
xlabel('Valeur')
ylabel('Nb occurences')

show() #affichage des courbes
Affichage d'un histogramme

L’exemple ci-dessous montre comment réaliser une regression polynomiale sur un ensemble de mesures bruitées. Le bruit est généré avec Scipy et la regression est effectuée par Numpy. L’affichage des courbes s’obtient simplement en appelant la fonction plot de Matplotlib.

from numpy import * #import de numpy
from pylab import * #import de matplotlib.pylab
from scipy.stats import norm #import du module norm de scipy.stats

t=arange(0,5,0.1)
c=[1,2,2] #Définition du polynome (t**2+2*t+2)
y=polyval(c,t) #Evaluation du polynome
yn=y+norm.rvs(size=len(t)) #Ajout d'un bruit gaussian

c_est = np.polyfit(t, yn, 2) #regression polynomiale (degré 2)
y_est=polyval(c_est,t)
plot(t,yn,'o',label="mesure") #Affichage des points
plot(t,y_est,label="regression")#Affichage des points
xlabel('temps')
ylabel('signal')
legend()
show() #affichage des courbes
Regression Polynomiale