Tracer les courbes ================== Le module Matplotlib est chargé de tracer les courbes: >>> import matplotlib.pyplot as plt D'une manière générale les fonctions ``plt.plot`` attendent des vecteur/matrice, bref des tableaux de points du plan. Selon les options, ces points du plan sont reliés entre eux de façon ordonnée par des segments : le résultat est une courbe. Commençons par la fonction sinus. .. plot:: :include-source: import matplotlib.pyplot as plt import numpy as np x=np.linspace(-5,5,100) plt.plot(x,np.sin(x)) # on utilise la fonction sinus de Numpy plt.ylabel('fonction sinus') plt.xlabel("l'axe des abcisses") plt.show() Si tout se passe bien, une fenêtre doit s'ouvrir avec la figure ci-dessus. Il est possible de jouer avec les menus dans le bas de cette fenêtre : zoomer, déplacer la figure, etc et surtout sauvegarder dans un format PNG, PDF, EPS, etc. :func:`plt.clf()` efface la fenêtre graphique :func:`plt.savefig()` sauvegarde le graphique. Par exemple ``plt.savefig("mongraphe.png")`` sauve sous le nom "mongraphe.png" le graphique. Par défaut le format est PNG. Il est possible d'augmenter la résolution, la couleur de fond, l'orientation, la taille (a0, a1, lettertype, etc) et aussi le format de l'image. Si aucun format n'est spécifié, le format est celui de l'extension dans "nomfigure.ext" (où "ext" est "eps", "png", "pdf", "ps" ou "svg"). Il est toujours conseillé de mettre une extension aux noms de fichier ; si vous y tenez ``plt.savefig('toto',format='pdf')`` sauvegarder l'image sous le nom "toto" (sans extension !) au format "pdf". Comportement en mode interactif ------------------------------- En mode interactif Python ou IPython, une caractéristique est le mode `interactif` de cette fenêtre **graphique**. Si vous avez tapé l'exemple précédent, et si cette fenêtre n'a pas été fermée alors la commande ``plt.xlabel("ce que vous voulez")`` modifiera l'étiquette sous l'axe des abcisses. Si vous fermez la fenêtre alors la commande ``plt.xlabel("ce que vous voulez")`` se contentera de faire afficher une fenêtre graphique avec axe des abcisses, des ordonnées allant de 0 à 1 et une étiquette "ce que vous voulez" sous l'axe des abcisses. L'équivalent "non violent" de `fermer la fenêtre` est la commande ``plt.close()``. L'inconvénient, une fois un premier graphique fait, est le ré-affichage ou l'actualisation de cette fenêtre graphique au fur et à mesure des commandes graphiques : lenteur éventuelle si le graphique comporte beaucoup de données. Il est donc indispensable de pouvoir suspendre ce mode interactif. Heureusement tout est prévu ! :func:`plt.isinteractive()` Retourne `True` ou `False` selon que la fenêtre graphique est interactive ou non. :func:`plt.ioff()` Coupe le mode interactif. :func:`plt.ion()` Met le mode interactif. :func:`plt.draw()` Force l'affichage (le "retraçage") de la figure. Ainsi une fois la première figure faite pour revenir à l'état initial, les deux commandes ``plt.close()`` et ``plt.ioff()`` suffisent. Des détails ----------- Pour connaître toutes les options, le mieux est de se référer à la documentation de Matplotlib. Voyons ici quelques unes d'entre elles * bornes : spécifier un rectangle de représentation, ce qui permet un zoom, d'éviter les grandes valeurs des fonctions par exemple, se fait via la commande ``plt.axis([xmin,xmax,ymin,ymax])`` * couleur du trait : pour changer la couleur du tracé une lettre ``g`` vert (green), ``r`` rouge (red), ``k`` noir, ``b`` bleu, ``c`` cyan, ``m`` magenta, ``y`` jaune (yellow), ``w`` blanc (white). ``plt.plot(np.sin(x),'r')`` tracera notre courbe sinus en rouge. Les amateurs de gris sont servis via ``color='(un flottant entre 0 et 1)'``. Enfin pour avoir encore plus de couleurs, comme en HTML la séquence ``color='#eeefff'`` donnera la couleur attendu et les amateurs de RGB sont servis par ``color=( R, G, B)`` avec trois paramètres compris entre 0 et 1 (RGBA est possible aussi). * symboles : mettre des symboles aux points tracés se fait via l'option ``marker``. Les possibilités sont nombreuses parmi ``[ ‘+’ | ‘*’ | ‘,’ | ‘.’ | ‘1’ | ‘2’ | ‘3’ | ‘4’ | ‘<’ | ‘>’ | ‘D’ | ‘H’ | ‘^’ | ‘_’ | ‘d’ | ‘h’ | ‘o’ | ‘p’ | ‘s’ | ‘v’ | ‘x’ | ‘|’ | TICKUP | TICKDOWN | TICKLEFT | TICKRIGHT | ‘None’ | ‘ ‘ | ‘’ ]``. * style du trait : pointillés, absences de trait, etc se décident avec ``linestyle``. Au choix ``'-'`` ligne continue, ``'--'`` tirets, ``'-.'`` points-tirets, ``':'`` pointillés, sachant que ``'None'``, ``''``, ``' '`` donnent "rien-du-tout". Plutôt que ``linestyle``, ``ls`` (plus court) fait le même travail. * épaisseur du trait : ``linewidth=flottant`` (comme ``linewidth=2``) donne un trait, pointillé (tout ce qui est défini par style du trait) d'épaiseur "flottant" en ``points``. Il est possible d'utiliser ``lw`` en lieu et place de ``linewidth``. * taille des symboles (markers) : ``markersize=flottant`` comme pour l'épaisseur du trait. D'autres paramètres sont modifiables ``markeredgecolor`` la couleur du trait du pourtour du marker, ``markerfacecolor`` la couleur de l'intérieur (si le marker possède un intérieur comme ``'o'``), ``markeredgsize=flottant`` l'épaisseur du trait du pourtour du marker. Remarquez que si la couleur n'est pas spécifiée pour chaque nouvel appel la couleur des "markers" change de façon cyclique. * étiquettes sur l'axe des abcisses/ordonnées : Matplotlib décide tout seul des graduations sur les axes. Tout ceci se modifie via ``plt.xticks(tf)``, ``plt.yticks(tl)`` où ``tf`` est un vecteur de flottants ordonnés de façon croissante. * ajouter un titre : ``plt.title("Mon titre")`` * légendes : c'est un peu plus compliqué. D'après ce que j'ai compris il faut assigner à des variables le tracé, via ``g1=plt.plot()``, etc. Enfin ``plt.legend((g1, g2), ("ligne 2","ligne 1"))`` fait le boulot. Par exemple .. plot:: :include-source: import matplotlib.pyplot as plt import numpy as np x=np.linspace(-5,5,100) p1=plt.plot(x,np.sin(x),marker='o') p2=plt.plot(x,np.cos(x),marker='v') plt.title("Fonctions trigonometriques") # Problemes avec accents (plot_directive) ! plt.legend([p1, p2], ["Sinus", "Cosinus"]) plt.show() Quelques exemples ----------------- Pour superposer plusieurs graphes de fonctions, il est possible de faire une succession de commandes ``plt.plot`` ou encore en une seule commande. Remarquez aussi que pour des choses simples il est possible de se passer des ``ls``, ``color`` et ``marker``. .. plot:: :include-source: import matplotlib.pyplot as plt import numpy as np t1=np.linspace(0,5,10) t2=np.linspace(0,5,20) plt.plot(t1, t1, 'r--', t1, t1**2, 'bs', t2, t2**3, 'g^-') Donner comme deuxième argument (abscisses) une matrice qui a autant de ligne que l'argument des abscisses est possible .. plot:: :include-source: import matplotlib.pyplot as plt import numpy as np x=np.linspace(-5,5,100) y=np.zeros((100,2)) y[:,0]=np.sin(x) y[:,1]=np.cos(x) plt.plot(x,y) plt.show() Si un seul vecteur (ou une seule matrice) est donné, on trace le graphe avec comme abscisse l'indice des éléments .. plot:: :include-source: import matplotlib.pyplot as plt import numpy as np x=np.linspace(-5,5,100) y=np.zeros((100,2)) y[:,0]=np.sin(x) y[:,1]=np.cos(x) plt.plot(y) plt.show() Enfin un système de `sous-figures` permet de juxtaposer différents graphiques .. plot:: :include-source: import numpy as np import matplotlib.pyplot as plt def f(t): import numpy as np # non necessaire import matplotlib.pyplot as plt # non necessaire return np.exp(-t) * np.cos(2*np.pi*t) t1 = np.arange(0.0, 5.0, 0.1) t2 = np.arange(0.0, 5.0, 0.02) plt.figure(1) plt.subplot(221) plt.plot(t1, f(t1), 'bo', t2, f(t2), 'k') plt.subplot(222) plt.plot(t2, np.cos(2*np.pi*t2), 'r--') plt.subplot(223) plt.plot(t2, np.sin(2*np.pi*t2), 'b-') Dans la commande ``plt.subplot`` l'argument est ``nbre de lignes, nbre de colonnes, numéro de la figure``. Il y a une condition à respecter : le nombre de lignes multiplié par le nombre de colonnes est supérieur ou égal au nombre de figure. Ensuite Matplotlib place les figures au fur et à mesure dans le sens des lignes. Dans le même registre, ouvrir plusieurs fenêtres graphiques est possible. Si vous avez déjà une fenêtre graphique, la commande ``plt.figure(2)`` en ouvre une seconde et les instructions ``plt.plot`` qui suivent s'addresseront à cette seconde figure. Pour revenir et modifier la première fenêtre graphique, ``plt.figure(1)`` suffit. Pour terminer, un histogramme et un affichage de texte sur le graphique .. plot:: :include-source: import numpy as np import matplotlib.pyplot as plt mu, sigma = 100, 15 x = mu + sigma * np.random.randn(10000) # histogramme des donn\'es n, bins, patches = plt.hist(x, 50, normed=1, facecolor='g', alpha=0.75) plt.xlabel('Donn\'ees') plt.ylabel('Probabilite') plt.title('Histogramme') plt.text(60, .025, r'$\mu=100,\ \sigma=15$') plt.axis([40, 160, 0, 0.03]) plt.grid(True) Certains graphiques (évolution de l'erreur dans une approximation numérique) demandent une échelle logarithmique (simple ou double). Les commandes ``plt.semilogx()``, ``plt.semilogy()`` et ``plt.loglog()`` mettent respectivement le graphe à l'échelle logarithmique simple en ``x``, logarithmique simple en ``y`` et double échelle logarithmique. .. plot:: :include-source: import numpy as np import matplotlib.pyplot as plt x=np.linspace(1,1000,50) plt.loglog() plt.plot(x,1./x) plt.plot(x,1./x**2) plt.show()