Tracer des courbes avec matplotlib
Créez un compte gratuit pour suivre votre avancement et reprendre où vous avez laissé.
Créer un compteTracer des courbes en Python
Dans la fiche précédente, tu as représenté une suite par un nuage de points : pour chaque $n$ entier, un point $(n, u_n)$. Une fonction $f$ se représente, elle, par une courbe continue. En Python, on triche un peu : on échantillonne $f$ sur de très nombreuses valeurs de $x$ et on relie les points par des segments. À l'œil, le résultat est indissociable d'une vraie courbe.
À la fin de cette fiche, tu sauras générer un tableau d'abscisses avec numpy, tracer la courbe représentative d'une fonction avec plt.plot, habiller le graphique (titre, axes, grille, légende), superposer plusieurs courbes, et tracer des courbes paramétriques.
Remarque
Comment lire cette fiche. Tu vas rencontrer deux types d'exercices à la suite des explications :
- Complète le programme — 1 ou 2 mots à compléter, juste après chaque nouveau concept.
- À toi de jouer — un petit programme à finir, en fin de section.
Chaque cellule s'exécute en cliquant sur Exécuter. Les premiers tracés peuvent prendre quelques secondes : le navigateur télécharge matplotlib et numpy. Ensuite, c'est instantané.
De la suite à la courbe
Une fonction $f : \mathbb{R} \to \mathbb{R}$ a une infinité d'images. Impossible de toutes les calculer. L'astuce : on choisit un grand nombre de valeurs $x_0, x_1, \dots, x_n$ régulièrement espacées dans un intervalle, on calcule les $f(x_i)$, et on demande à plt.plot de relier les points consécutifs par un segment. Avec 200 ou 500 points, l'œil voit une courbe lisse.
Cette première version utilise une compréhension de liste, exactement comme dans la fiche sur les suites. Ça marche très bien pour 60 points. Mais dès qu'il faut en générer 1000 ou écrire $\sin(x)$ pour chaque $x$, la solution devient lourde. C'est là qu'intervient numpy.
Complète le programme
Trace la courbe de $f(x) = x^3$ sur $[-2, 2]$ en utilisant 41 points (pas de $0{,}1$) :
Voir la solution
import matplotlib.pyplot as plt
abscisses = [-2 + 0.1 * k for k in range(41)]
ordonnees = [x ** 3 for x in abscisses]
plt.plot(abscisses, ordonnees)
plt.grid(True)
plt.show()Complète le programme
Même exercice pour $f(x) = 2x + 1$ sur $[0, 5]$ avec 51 points (pas de $0{,}1$) :
Voir la solution
import matplotlib.pyplot as plt
abscisses = [0.1 * k for k in range(51)]
ordonnees = [2 * x + 1 for x in abscisses]
plt.plot(abscisses, ordonnees)
plt.grid(True)
plt.show()À toi de jouer
Trace la courbe de $f(x) = -x^2 + 4$ sur $[-3, 3]$, avec un pas suffisamment petit pour que la courbe paraisse lisse. Repère graphiquement les zéros de $f$ : ils doivent tomber sur $x = -2$ et $x = 2$.
Voir la solution
import matplotlib.pyplot as plt
abscisses = [-3 + 0.05 * k for k in range(121)]
ordonnees = [-x ** 2 + 4 for x in abscisses]
plt.plot(abscisses, ordonnees)
plt.grid(True)
plt.show()Remarque
Spécificité Python — plot vs scatter. Tu as utilisé plt.scatter dans la fiche sur les suites pour tracer des points isolés. Ici, plt.plot relie les points successifs par des segments. Si tu remplaces plot par scatter, tu verras les 60 points individuels au lieu d'une courbe — c'est la même donnée, deux représentations différentes.
numpy : un tableau d'abscisses en une ligne
numpy est la bibliothèque scientifique de référence en Python. Sa fonction linspace(a, b, n) crée un tableau de $n$ valeurs régulièrement réparties entre $a$ et $b$ (bornes incluses). Plus besoin de calculer le pas à la main.
Le résultat est un ndarray (tableau numpy), pas une liste Python ordinaire. Sa force : les opérations arithmétiques s'appliquent à tout le tableau d'un coup, sans boucle. C'est la vectorisation.
Pour tracer une courbe, on combine linspace et la vectorisation. Le code devient nettement plus court et plus rapide :
Complète le programme
Crée un tableau de 100 valeurs régulièrement réparties entre $-5$ et $5$, puis trace $f(x) = x^3 - 3x$ :
Voir la solution
import numpy as np
import matplotlib.pyplot as plt
x = np.linspace(-5, 5, 100)
y = x ** 3 - 3 * x
plt.plot(x, y)
plt.grid(True)
plt.show()Complète le programme
numpy connaît les fonctions usuelles : np.sin, np.cos, np.exp, np.log, np.sqrt. Trace la courbe de $f(x) = \sin(x)$ sur $[-2\pi, 2\pi]$ avec 300 points :
Voir la solution
import numpy as np
import matplotlib.pyplot as plt
x = np.linspace(-2 * np.pi, 2 * np.pi, 300)
y = np.sin(x)
plt.plot(x, y)
plt.grid(True)
plt.show()À toi de jouer
Trace la courbe de $f(x) = \dfrac{1}{1 + x^2}$ sur $[-5, 5]$ avec 400 points. C'est la fonction « cloche » qui apparaît en probabilités. Utilise la vectorisation : pas de boucle for.
Voir la solution
import numpy as np
import matplotlib.pyplot as plt
x = np.linspace(-5, 5, 400)
y = 1 / (1 + x ** 2)
plt.plot(x, y)
plt.grid(True)
plt.show()Remarque
Spécificité Python — la vectorisation numpy. Quand tu écris y = x ** 2 avec un tableau numpy x, la mise au carré est exécutée par du code C compilé en arrière-plan, pas par une boucle Python. C'est typiquement 50 à 100 fois plus rapide qu'une compréhension de liste équivalente. La même opération sur une liste Python ordinaire ([1, 2, 3] ** 2) déclencherait une TypeError : seules les listes numpy savent multiplier élément par élément.
Habiller un graphique
Une courbe sans titre ni axes étiquetés, c'est un graphique inutilisable. matplotlib propose une série d'instructions à appeler avant plt.show() :
plt.title("...")— un titreplt.xlabel("...")etplt.ylabel("...")— étiquettes des axesplt.grid(True)— quadrillageplt.axhline(0, color='black')— axe horizontal noirplt.axvline(0, color='black')— axe vertical noirplt.xlim(a, b)etplt.ylim(c, d)— bornes des axes
Pour la couleur et le style du tracé, plot accepte des arguments comme color (noms ou codes hex), linestyle ('--', ':', '-.') et linewidth.
Complète le programme
Reprends la courbe de $f(x) = x^2 - 4$ et ajoute un titre et des étiquettes d'axes :
Voir la solution
import numpy as np
import matplotlib.pyplot as plt
x = np.linspace(-5, 5, 200)
y = x ** 2 - 4
plt.plot(x, y)
plt.title('Parabole')
plt.xlabel('x')
plt.ylabel('f(x)')
plt.grid(True)
plt.show()Complète le programme
Trace $f(x) = \cos(x)$ sur $[-2\pi, 2\pi]$ avec un trait pointillé rouge (linestyle='--', color='red') :
Voir la solution
import numpy as np
import matplotlib.pyplot as plt
x = np.linspace(-2 * np.pi, 2 * np.pi, 300)
y = np.cos(x)
plt.plot(x, y, linestyle='--', color='red')
plt.grid(True)
plt.show()À toi de jouer
Trace la courbe de $f(x) = \sqrt{x}$ sur $[0, 9]$. Habille le graphique : titre, étiquettes, quadrillage, et force les bornes verticales avec plt.ylim(0, 4). Choisis une couleur de ton choix.
Voir la solution
import numpy as np
import matplotlib.pyplot as plt
x = np.linspace(0, 9, 200)
y = np.sqrt(x)
plt.plot(x, y, color='teal')
plt.title('Racine carrée')
plt.xlabel('x')
plt.ylabel('sqrt(x)')
plt.ylim(0, 4)
plt.grid(True)
plt.show()Remarque
Spécificité Python — l'API « pyplot » est impérative. Chaque appel à plt.title, plt.xlabel, plt.plot s'applique à la figure courante, dans l'état où elle est. C'est très différent d'un objet « graphique » que tu construirais en Java. L'avantage : on enchaîne les commandes naturellement. L'inconvénient : si tu oublies plt.show() ou si tu mélanges deux graphiques dans la même cellule, tu obtiens du n'importe quoi. Règle : un graphique = une cellule, terminée par plt.show().
Plusieurs courbes sur un même graphique
Pour comparer deux fonctions, on appelle plt.plot plusieurs fois avant le plt.show(). Chaque appel ajoute une courbe à la figure courante. On utilise l'argument label et la fonction plt.legend() pour identifier chaque courbe.
Cette technique est très utile pour visualiser une résolution graphique : tracer $y = f(x)$ et $y = g(x)$ sur le même repère, puis lire les abscisses des points d'intersection.
Complète le programme
Trace sur le même graphique $f(x) = \sin(x)$ et $g(x) = \cos(x)$ sur $[-2\pi, 2\pi]$, avec leurs légendes :
Voir la solution
import numpy as np
import matplotlib.pyplot as plt
x = np.linspace(-2 * np.pi, 2 * np.pi, 300)
plt.plot(x, np.sin(x), label='sin')
plt.plot(x, np.cos(x), label='cos')
plt.legend()
plt.grid(True)
plt.show()Complète le programme
On veut comparer une fonction et sa dérivée approchée. Trace $f(x) = x^2$ et $f'(x) = 2x$ sur $[-3, 3]$ :
À toi de jouer
Résous graphiquement l'équation $\mathrm{e}^x = 3 - x$ : trace les deux courbes $y = \mathrm{e}^x$ et $y = 3 - x$ sur $[-2, 2]$, et lis l'abscisse approximative de leur point d'intersection. Ajoute titre, légende et quadrillage.
Remarque
Spécificité Python — couleurs automatiques. Quand tu enchaînes plusieurs plt.plot sans préciser de couleur, matplotlib choisit pour toi des couleurs distinctes dans une palette préconfigurée (bleu, orange, vert, rouge…). C'est rare dans les bibliothèques graphiques bas niveau (en C ou Java, il faut souvent gérer la palette à la main). Tu peux toujours imposer ta couleur avec color='...' si tu veux respecter une charte graphique précise.
Courbes paramétriques
Une courbe paramétrique se décrit par deux fonctions du temps : $x(t)$ et $y(t)$. Tracer la courbe revient alors à tracer le nuage des points $(x(t), y(t))$ pour $t$ parcourant un intervalle. C'est exactement la même API : plt.plot(x_array, y_array).
L'astuce plt.gca().set_aspect('equal') force les axes à la même échelle : sans elle, le cercle aurait l'air d'une ellipse aplatie. Tu peux aussi tracer des courbes plus exotiques :
Complète le programme
Trace une ellipse de demi-axes $a = 3$ et $b = 1$ : équations paramétriques $x(t) = a \cos(t)$, $y(t) = b \sin(t)$ pour $t \in [0, 2\pi]$.
Voir la solution
import numpy as np
import matplotlib.pyplot as plt
t = np.linspace(0, 2 * np.pi, 200)
x = 3 * np.cos(t)
y = 1 * np.sin(t)
plt.plot(x, y)
plt.gca().set_aspect('equal')
plt.grid(True)
plt.show()Complète le programme
Trace une spirale d'Archimède : $x(t) = t \cos(t)$, $y(t) = t \sin(t)$ pour $t \in [0, 8\pi]$ avec 500 points.
Voir la solution
import numpy as np
import matplotlib.pyplot as plt
t = np.linspace(0, 8 * np.pi, 500)
x = t * np.cos(t)
y = t * np.sin(t)
plt.plot(x, y)
plt.gca().set_aspect('equal')
plt.show()À toi de jouer
Trace une courbe de Lissajous : $x(t) = \sin(3t)$, $y(t) = \sin(2t)$ pour $t \in [0, 2\pi]$ avec 500 points. Force le repère orthonormé. Tu devrais obtenir une figure fermée à plusieurs lobes.
Voir la solution
import numpy as np
import matplotlib.pyplot as plt
t = np.linspace(0, 2 * np.pi, 500)
x = np.sin(3 * t)
y = np.sin(2 * t)
plt.plot(x, y)
plt.gca().set_aspect('equal')
plt.title('Lissajous 3:2')
plt.grid(True)
plt.show()Remarque
Spécificité Python — la même fonction pour tout. Que tu traces une courbe de fonction $y = f(x)$, un nuage de points expérimentaux, une suite récurrente ou une courbe paramétrique, tu utilises plt.plot(x, y) avec deux tableaux. C'est ce qu'on appelle une API uniforme. En MATLAB, l'API est très proche (matplotlib s'en est inspiré). En JavaScript ou en C, il faudrait utiliser des bibliothèques entièrement différentes (D3, Cairo) qui n'ont pas cette ergonomie.
Pour aller plus loin
Plusieurs sous-graphiques avec subplots. Pour mettre côte à côte plusieurs courbes au lieu de les superposer, on crée une grille de sous-graphiques. Chaque case s'appelle un axes et expose les mêmes méthodes que plt.
Le « broadcasting » de numpy. Quand tu écris 2 * x + 1 avec x tableau, numpy comprend qu'il faut multiplier chaque valeur par 2 puis ajouter 1. C'est ce qu'on appelle le broadcasting : les opérations s'étendent automatiquement entre scalaires et tableaux, ou même entre tableaux de tailles compatibles. Cette mécanique est unique aux bibliothèques scientifiques (numpy, MATLAB) — Java, C ou JavaScript ne l'ont pas en natif et exigent une boucle explicite.
Animer une courbe. Avec un peu plus de matplotlib, on peut faire évoluer une courbe en temps réel. La technique typique : on calcule plusieurs « images » et on les affiche successivement. Voici une animation discrète qui montre l'effet d'un paramètre $a$ sur la courbe $y = a \sin(x)$.
Tracer une courbe à partir de données expérimentales. Quand les valeurs viennent d'une mesure, matplotlib permet de combiner plot (la courbe modèle) et scatter (les points mesurés). C'est une figure très courante en physique-chimie ou en SVT.
Comparaison avec d'autres outils. Pour la 3D ou l'interactivité (zoom, rotation), matplotlib reste un peu rustique : on lui préfère alors plotly (graphes web interactifs) ou bokeh. Pour de très gros volumes (millions de points), datashader est imbattable. Mais pour 99 % des besoins lycée et premier cycle, matplotlib est l'outil standard, indissociable de la culture scientifique Python.
À toi de jouer
Trace la famille des paraboles $y = x^2 + c$ pour $c$ allant de $-3$ à $3$ par pas de $1$, sur $[-3, 3]$. Toutes sur le même graphique, avec une légende label=f'c = {c}'. Tu dois voir 7 paraboles décalées verticalement.
Voir la solution
import numpy as np
import matplotlib.pyplot as plt
x = np.linspace(-3, 3, 200)
for c in range(-3, 4):
plt.plot(x, x ** 2 + c, label=f'c = {c}')
plt.legend()
plt.grid(True)
plt.title('Famille y = x² + c')
plt.show()Ce que tu as appris
- Une courbe en Python = un tableau d'abscisses + un tableau d'ordonnées +
plt.plot(x, y). numpy.linspace(a, b, n)crée $n$ valeurs régulièrement réparties entre $a$ et $b$.- Les opérations vectorisées (
x ** 2,np.sin(x)) s'appliquent à tout le tableau d'un coup, sans boucle. - Pour habiller un graphique :
plt.title,plt.xlabel,plt.ylabel,plt.grid(True),plt.legend(). - Plusieurs
plt.plotavant un seulplt.show()superposent les courbes ; chacune avec sonlabel. - Une courbe paramétrique se trace pareil : deux tableaux $(x(t), y(t))$ et
set_aspect('equal')pour le repère orthonormé. - Pour des grilles de figures,
subplots; pour de l'interactivité,plotly.
Et après…
Tu vas combiner random et matplotlib pour simuler des expériences aléatoires (lancers de pièces, marches aléatoires, méthode de Monte-Carlo) et observer la loi des grands nombres en direct.