Tracer des courbes (matplotlib) Tuto

Tracer des courbes avec matplotlib

Durée estimée
15 minutes
Votre progression

Créez un compte gratuit pour suivre votre avancement et reprendre où vous avez laissé.

Créer un compte

Tracer 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 titre
  • plt.xlabel("...") et plt.ylabel("...") — étiquettes des axes
  • plt.grid(True) — quadrillage
  • plt.axhline(0, color='black') — axe horizontal noir
  • plt.axvline(0, color='black') — axe vertical noir
  • plt.xlim(a, b) et plt.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.plot avant un seul plt.show() superposent les courbes ; chacune avec son label.
  • 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.