Voici un plot simple
# -*- coding: utf-8 -*-
"""
Exemple de plot
"""
from __future__ import division
from scipy import *
from pylab import *
x = linspace(0,10,400)
y = sin(x)*exp(-x/5)
plot(x,y)
show()
ce qui donne
Dans cette section, nous traiterons de l’édition simple d’un graphique : mettre en place un titre, des étiquettes sur les axes, une légende ou mettre en forme les différentes courbes
Pour inclure un titre et des étiquettes sur les axes, on utilise les codes
title(ur"Titre")
xlim(lim1, lim2)
xlabel(u"LabelX")
Voici une utilisation sur un exemple
# -*- coding: utf-8 -*-
"""
Exemple de plot
Edition des axes et du titre
"""
from __future__ import division
from scipy import *
from pylab import *
t = linspace(0,10,400) # Temps = Abscisses
U1 = sin(t)*exp(-t/5) # Tension = Ordonnées
plot(t,U1) # Graphique
title(u"Ma belle figure", fontsize=16) # Edition du titre
xlim(-5, 15) # Limites de l'axe des abscisses
xlabel(ur"$t \, (s)$", fontsize=16) # Label de l'axe des abscisses
ylim(-1.5, 1.5) # Limites de l'axe des ordonnées
ylabel(ur"$U_{1} \, (V)$", fontsize=16) # Label de l'axe des ordonnées
show()
ce qui donne
Pour ajouter une légende, on utilise le code legend()
Voici une utilisation sur un exemple
# -*- coding: utf-8 -*-
"""
Exemple de plot
Création d'une légende
"""
from __future__ import division
from scipy import *
from pylab import *
t = linspace(0,10,400) # Temps = Abscisses
def U(t,Q):
return exp(-2/Q*t)*cos(2*pi*t) # Fonction U dépendant d'un paramètre Q
plot(t,U(t,2),label=ur"$Q=2$") # Plot1 avec Q = 2 et édition du label correspondant
plot(t,U(t,10),label=ur"$Q=10$") # Plot2 avec Q = 10 et édition du label correspondant
xlim(0, 10) # Limites de l'axe des abscisses
xlabel(ur"$t \, (s)$", fontsize=16) # Label de l'axe des abscisses
ylim(-1, 1) # Limites de l'axe des ordonnées
ylabel(ur"$U \, (V)$", fontsize=16) # Label de l'axe des ordonnées
legend() # Appel de la légende
show()
ce qui donne
On peut directement le télécharger.
Enfin pour mettre en forme les courbes (couleur et forme, marqueurs...), il existe 2 méthodes : la méthode explicite où les commandes sont employées en toutes lettres et la méthode rapide où les commandes sont utilisées sous forme d’alias et de racourcis. Reprenons l’exemple précédent et changeons la mise en forme des courbes.
# -*- coding: utf-8 -*-
"""
Exemple de plot
Mise en forme des courbes
"""
from __future__ import division
from scipy import *
from pylab import *
t = linspace(0,10,100) # Temps = Abscisses
def U(t,a):
return exp(-1/3*t)*cos(2*pi*t) + a # Fonction U dépendant d'un paramètre a (décalage)
plot(t,U(t,0),'or',label=ur"$or$") # Plot1 avec une première mise en forme
plot(t,U(t,2),'-og',label=ur"$-og$") # Plot2
plot(t,U(t,4),'--xb',label=ur"$--xb$") # Plot3
plot(t,U(t,6),':',label=ur"$:$") # Plot4
xlim(0, 10) # Mise en forme des axes
xlabel(ur"$t \, (s)$", fontsize=16)
ylim(-1, 7)
ylabel(ur"$U \, (V)$", fontsize=16)
legend() # Appel de la légende
show()
ce qui donne
On peut donc utiliser les mises en forme suivantes
Mise en forme | Commande | racourci | Valeurs |
---|---|---|---|
Style de ligne | linestyle | ls | - ou –- ou -. ou : |
Epaisseur de ligne | linewidth | lw | Valeur décimale |
Type de marqueurs | marker | ... | o ou + ou , ou . ou x ou 1 ou 2 ou 3 ou 4 |
Taille des marqueurs | markersize | ms | Valeur décimale |
Couleur des marqueurs | markerfacecolor | mfc | Couleur matplotlib |
Taille des contours des marqueurs | markeredgewidth | mew | Valeur décimale |
Couleur des contours des marqueurs | markeredgecolor | mec | Couleur matplotlib |
Pour la mise en forme des courbes, on pourra se reporter à la documentation de Matplotlib p.22.
Exemples de couleurs matplotlib
Couleurs | Commande | racourci |
---|---|---|
Bleu | blue | b |
Vert | green | g |
Rouge | red | r |
Magenta | magenta | c |
Jaune | yellow | y |
Noir | black | k |
Blanc | white | w |
Pour les couleurs des courbes, on pourra se reporter à la documentation de Matplotlib p.697.
Pour finir, on pourra essayer par erxemple le code
plot(x,y,'o-', lw=3, ms=12, mfc='w', mec='b', mew=3)
Pour tracer des points et des lignes, le plus facile reste de tracer un graphique point à point avec une mise en forme appropriée, du type
plot([xA,xB],[yA,yB],'k--') # Ligne pointillé noire
plot([xI],[yI],'or') # Point rouge
text(xt, yt, ur"$1$", fontsize=20, color='b', backgroundcolor='w') # Texte bleu sur fond blanc
Le texte a été traité dans le chapitre sur les chaînes de caractères (voir le chapitre dédié). Les flèches ont une nomenclature particulière (Pour plus de détails, on pourra se reporter à la documentation de Matplotlib p.17,57-60,147-159) :
annotate(ur"$Commentaire$", fontsize=16,xy=(x1,y1), xycoords='data',xytext=(x2,y2), textcoords='data',arrowprops=dict(arrowstyle="->",connectionstyle="arc3",color='k'), )
Voici un exemple de graphique réalisé avec le fichier suivant. :
Pour tracer des graphiques avec des fenêtres séparées, il faut utiliser le code
figure1 = figure()
plot(...)
figure2 = figure()
plot(...)
show()
Note
Les instructions données après le code figure2 = figure() ne seront valables que pour celle-ci, comme le montre ce fichier exemple où les axes ne sont annotés, la légende n’est placée et les échelles ne sont respectées que pour la figure 2.
Pour tracer des sous-graphiques, on utilise les commandes subplot2grid, subplot et add_subplot. Les détails sont donnés dans la documentation de la librairie Matplotlib p.89-110.
Un exemple d’utilisation est
# -*- coding: utf-8 -*-
"""
Exemple de plot
Sous graphiques : subplots
"""
from __future__ import division
from scipy import *
from pylab import *
x = logspace(-2,2, 500) # x=omega/omega0 = Abscisses
def H(x, Q): # Fonction de transfert
return 1/(1+1j*x/Q-x**2)
"""
Rejecteur (1-x**2)/(1+1j*x/Q-x**2)
Passe haut -x**2/(1+1j*x/Q-x**2)
Passe bas 1/(1+1j*x/Q-x**2)
Passe bande 1j*x/Q/(1+1j*x/Q-x**2)
"""
Qvaleurs = [0.1, 1/sqrt(2), 3] # Valeurs désirées du facteur de qualité
fig = plt.figure()
fig.subplots_adjust(hspace=0.1) # Espace entre les graphiques
"""
### Graphique de l'amplitude
"""
ax = fig.add_subplot(211)
for Q in Qvaleurs : # Boucle for pour tracer les graphiques
legende=u"$Q = %4.1f$" %(Q) # Légende automatique : conversion en str du facteur de qualité
plot(log10(x), 20*log10(abs(H(x, Q)) ), label=legende,lw=1.5) # Graphiques
xlim(-2, 2) # Limites de l'axe des abscisses
ax.set_xticklabels([]) # Pas de labels sur l'axe des x
ylim(-60., 20) # Limites de l'axe des ordonnées
ylabel(ur"$G^{dB}=20.log_{10}(|H|)$", fontsize=16) # Label de l'axe des ordonnées
legend() # Appel de la légende
grid(True) # Grille
"""
### Graphique de la phase
"""
ax2 = fig.add_subplot(212)
for Q in Qvaleurs : # Boucle for pour tracer les graphiques
legende=u"$Q = %4.0f$" %(Q)
plot(log10(x), 180/3.1416*angle(H(x, Q)), label=legende,lw=1.5)
xlim(-2, 2) # Limites de l'axe des abscisses
xlabel(ur"$log_{10}(x) = log_{10}(\omega/\omega_{0})$", fontsize=16) # Label de l'axe des abscisses
ylim(-180., 0) # Limites de l'axe des ordonnées
ylabel(ur"$\phi \, (^\circ)$", fontsize=16) # Label de l'axe des ordonnées
grid(True) # Grille
show()
ce qui donne
Un autre exemple, dont le code est donné plus bas (graphiques en coordonnées semilogarithmiques ou logarithmiques) donne le résultat suivant
Pour choisir la taille des figures, on utilise la fonction figure(figsize=(a,b)) où a et b représente la largeur et la hauteur de l’image en pouces (valeur par défaut (8,6)). Pour la sauvegarde, on utilise la fonction savefig('NomFigure.png', dpi=200) où dpi (Dots Per Inch) représente le nombre de points par pouce (PPP).
Par exemple, une figure de taille (6,4) (figure(figsize=(6,4))) sauvée en 200 DPI (savefig('test.png', dpi=200)) aura pour taille 6*200 x 4*200 -> 1200x800. L’argument dpi= est facultatif et sa valeur par défaut est 100.
Pour plus de détails, on pourra se reporter à la documentation de Matplotlib p.924-925.
Voici un exemple :
# -*- coding: utf-8 -*-
"""
Exemple de plot
Sauvegarde de la figure en PNG / Taille de la figure
"""
from __future__ import division
from scipy import *
from pylab import *
t = linspace(0,10,400) # Temps = Abscisses
def U(t,Q):
return exp(-2/Q*t)*cos(2*pi*t) # Fonction U dépendant d'un paramètre Q
fig = figure(figsize=(4,6)) # Taille de la figure
plot(t,U(t,5),label=ur"$Q=5$") # Graphique
xlim(0, 10) # Mise en forme
xlabel(ur"$t \, (s)$", fontsize=16)
ylim(-1, 1)
ylabel(ur"$U \, (V)$", fontsize=16)
legend() # Appel de la légende
savefig('test1.png', dpi=50) # Export PNG dpi valeur par défaut 100 dpi
savefig('test2.png', dpi=100)
fig = figure(figsize=(10,6)) # Taille de la figure
plot(t,U(t,5),label=ur"$Q=5$") # Graphique
xlim(0, 10) # Mise en forme
xlabel(ur"$t \, (s)$", fontsize=16)
ylim(-1, 1)
ylabel(ur"$U \, (V)$", fontsize=16)
legend() # Appel de la légende
savefig('test3.png') # Export PNG
show()
qui donne suivant les paramètres d’exportation
09 En construction
Les graphiques sont containts (constrained) lorsque les échelles dans les directions x et y ont les mêmes proportions. C’est une propriété utile si l’on veut vérifier si une figure est un cercle ou une ellipse (dans le cas des portraits de phase notamment). On utilise la commande :
axis('equal')
L’exemple suivant montre la différence entre 2 graphiques, l’un contraint et l’autre non.
# -*- coding: utf-8 -*-
"""
Exemple de plot
Graphiques sur fenêtres séparées
"""
from __future__ import division
from scipy import *
from pylab import *
t = linspace(0,2*pi,400) # Temps = paramètre
figure1 = figure() # Figure 1 : graphique non contraint
plot(cos(t),sin(t))
figure2 = figure() # Figure 2 : graphique contraint
plot(cos(t),sin(t))
axis('equal')
show()
ce qui donne
Note
La fonction axis('equal') change les limites des axes x et y pour arriver à une même échelle. La fonction axis('scaled') arrive au même résultat mais en changeant la taille de la zone de graphique sans changer d’échelle.
Il est possible de tracer un graphique en coordonnées semilogarithmiques ou logarithmiques à l’aide des fonctions semilogx, semilogy et loglog. L’exemple suivant monter un graphique tracé dans 4 systèmes de coordonnées.
# -*- coding: utf-8 -*-
"""
Exemple de plot
Graphiques en coordonnées semilogarithmiques ou logarithmiques
"""
from __future__ import division
from scipy import *
from pylab import *
xlin = linspace(0,2,400) # Abscisse linéaire
xlog = logspace(-2,4,400) # Abscisse logarithmique
def a(x, Q): # Module d'une fonction de transfert
return abs(1/(1+1j*x/Q-x**2))
# axes linéaires
subplot(221)
plot(xlin, a(xlin, 5))
title(u"lin")
grid(True)
# axe y logarithmique
subplot(222)
semilogy(xlin, a(xlin, 5))
title(u"semilogy")
grid(True)
# axe x logarithmique
subplot(223)
semilogx(xlog, a(xlin, 5))
title(u"semilogx")
grid(True)
# axes logarithmiques
subplot(224)
loglog(xlog, a(xlin, 5), basex=10)
grid(True)
title(u"loglog base 10 on x")
suptitle(u"Systèmes de coordonnées",fontsize=16)
show()
ce qui donne
Pour créer un graphique à légende automatique (tracé automatique en fonction d’un paramètre), il suffit de convertir le paramètre en chaîne de caractères et de l’insérer dans la légende, comme le montre le code suivant :
# -*- coding: utf-8 -*-
"""
Exemple de plot
Création d'une légende automatique en fonction d'un paramètre
"""
from __future__ import division
from scipy import *
from pylab import *
x = linspace(0,2,400) # x=omega/omega0 = Abscisses
def A(x,Q):
return 1/sqrt((1-x**2)**2+1/Q**2*x**2) # Fonction dépendant d'un paramètre Q
Qvaleurs = [0.1, 1/sqrt(2), 3, 5] # Valeurs désirées du facteur de qualité
for Q in Qvaleurs : # Boucle for pour tracer les graphiques
legende="$Q = %4.1f$" %(Q) # Légende automatique : conversion en str du facteur de qualité
plot(x, A(x, Q), label=legende,lw=1.5) # Graphique
xlim(0, 2) # Limites de l'axe des abscisses
xlabel(ur"$x=\omega/\omega_{0} \, (\varnothing)$", fontsize=16) # Label de l'axe des abscisses
ylim(0, 5.1) # Limites de l'axe des ordonnées
ylabel(ur"$A/A_{0} \, (\varnothing)$", fontsize=16) # Label de l'axe des ordonnées
legend() # Appel de la légende
show()
ce qui donne
Un graphique avec deux échelles (ou plus) différentes suivant l’axe des ordonnées est possible en utilisant la fonction twinx(). Voici un exemple
# -*- coding: utf-8 -*-
"""
Exemple de plot
Graphique avec deux échelles en Y
"""
from __future__ import division
from scipy import *
from pylab import *
x = linspace(0,2,400) # x=omega/omega0 = Abscisses
def H(x, Q): # Fonction de transfert
return 1/(1+1j*x/Q-x**2)
fig = plt.figure()
ax1 = fig.add_subplot(111)
ax1.plot(x, abs(H(x, 5)), '-b', label=ur"$A/A_{0}$",lw=1.5) # Graphique 1 avec le système d'axes 1
ylim(0, 5.1) # Limites de l'axe des ordonnées 1
ylabel(ur"$A/A_{0} \, (\varnothing)$", color='b', fontsize=16) # Label de l'axe des ordonnées 1
for tl in ax1.get_yticklabels(): # Couleur des étiquettes de l'axe des ordonnées 1
tl.set_color('b')
legend(loc=2) # Appel de la légende 1
ax2 = ax1.twinx() # Système d'axes 2
ax2.plot(x, 180/3.1416*angle(H(x, 5)),'--r', label=ur"$\phi \, (^\circ)$",lw=1.5) # Graphique 2 avec le système d'axes 2
ylim(-180, 0) # Limites de l'axe des ordonnées 2
ylabel(ur"$\phi \, (^\circ)$", color='r', fontsize=16) # Label de l'axe des ordonnées 2
for tl in ax2.get_yticklabels(): # Couleur des étiquettes de l'axe des ordonnées 2
tl.set_color('r')
legend(loc=1) # Appel de la légende 2
show()
ce qui donne
Pour modifier les étiquettes des graduations qui sont par défaut des numériques, il faut utilise la commande xticks ou yticks (documentation de Matplotlib p.959-962))
xticks( arange(9)*T/2, (ur"$0$", ur"$T/2$", ur"$T$", ur"$3T/2$", ur"$2T$", ur"$5T/2$", ur"$3T$", ur"$7T/2$", ur"$4T$"), fontsize=16)
yticks( arange(3)-1, (ur"$-U_{0}$" , ur"$ $", ur"$U_{0}$"), fontsize=16 )
Ce qui donne
Pour tracer un graphique avec des axes centrés ou des axes passant par 0, on utilise la fonction spines, comme dans l’exemple suivant
# -*- coding: utf-8 -*-
"""
Exemple de plot
Axes en position (0,0)
"""
from __future__ import division
from scipy import *
from pylab import *
x = linspace(-1, 2, 200) # Abscisses
def U(t):
return sin(2*pi*t) # Fonction à tracer
fig = figure()
ax = fig.add_subplot(111)
ax.plot(x,U(x)) # Graphique
ax.spines['left'].set_position('zero') # Propriétés des axes
ax.spines['right'].set_color('none')
ax.spines['bottom'].set_position('zero')
ax.spines['top'].set_color('none')
show()
ce qui donne
Une documentation plus explicite est donnée dans les pages de Matplotlib Spines
Pour tracer un graphique 3D en paramétrique, il suffit d’entrer 3 arrays et d’utiliser la librairie Axes3D, comme dans l’exemple suivant. Une boucle for permet aussi de tracer en paramétrique des segments qui représentent ici le champ électrique d’une onde électromagnétique polarisée circulairement.
# -*- coding: utf-8 -*-
"""
tracé des vecteurs champs E et B pour une OemPPH
"""
from __future__ import division
from scipy import *
from pylab import *
import matplotlib as mpl
from mpl_toolkits.mplot3d import Axes3D # librairie 3D
# Type de l'onde
E0y = 1
E0z = 1
phi = pi/2
T = 125
fig = figure()
ax = fig.gca(projection='3d')
x,y,z = array([]), array([]), array([])
for i in range(301):
x_fin=i
y_fin=E0y * cos(2*pi*i/T)
z_fin=E0z * cos(2*pi*i/T-phi)
plot([i,x_fin], [0,y_fin], [0,z_fin],color='b') # Champ E
x = append(x,x_fin)
y = append(y,y_fin)
z = append(z,z_fin)
plot(x, y, z,color='b',lw=2) # Contour du Champ E (paramétrique 3D)
show()
ce qui donne
Pour effectuer un graphique 3d de type map, on utilise la librairie Axes3D et on créée un maillage x,y uniforme avec la fonction meshgrid. On a, dans l’exemple, suivant le champ électrique d’une onde guidée entre 2 conducteurs (entre 0 et \(a\)).
dont le code est
# -*- coding: utf-8 -*-
"""
Champ électrique guidé
"""
from __future__ import division
from scipy import *
from pylab import *
from mpl_toolkits.mplot3d import Axes3D
fig = plt.figure()
ax = fig.gca(projection='3d')
a = 1
xlin = linspace(-5,5,500)
ylin = linspace(-a/2,3*a/2,500)
X, Y = meshgrid(xlin, ylin)
def Ampy(y):
if y <= 0:
return 0
if y>= a:
return 0
else:
return 1
Ampy_vect = vectorize(Ampy)
def Z(x,y,t):
return Ampy_vect(y)*sin(pi/a*y)*cos(2*pi*t-pi*x)
surf = ax.plot_surface(X, Y, Z(X,Y,0),color='r')
xlabel(ur"$x$", fontsize=16)
ylabel(ur"$z$", fontsize=16)
yticks( arange(2), (ur"$0$", ur"$a$"), fontsize=16)
show()
On peut aussi en faire une animation avec les méthodes développées dans le chapitre “animation”.