Physique-chimie · 1re · Enseignement de spécialité · Projet n°2

Une loi linéaire,
jusqu'à ce qu'elle ne le soit plus.

La loi de Beer-Lambert relie l'absorbance d'une solution colorée à sa concentration. Tu vas d'abord vérifier sa linéarité sur des solutions diluées de permanganate de potassium, puis — c'est tout l'intérêt de ce projet — la mettre en défaut à forte concentration, pour comprendre qu'un modèle a toujours un domaine de validité.

beer_lambert.py — aperçuC = 0.00
modèle mesure

Objectif du projet : étudier l'évolution de l'absorbance A d'une solution de permanganate de potassium en fonction de sa concentration C, vérifier la linéarité prédite par la loi de Beer-Lambert, puis montrer que cette loi cesse d'être valable à forte concentration.

Ce projet est autonome : tu n'as besoin d'aucun autre document, les données sont recopiées directement dans le script. Chaque étape contient un script incomplet à compléter, puis à copier-coller dans Thonny (ou dans la console Basthon tout en bas de la page si tu n'as pas Thonny sous la main).

00

Les données

À savoir
  • On étudie l'absorbance A d'une solution de permanganate de potassium (un colorant violet) mesurée au spectrophotomètre, pour 11 concentrations C différentes (en mol/L).
  • Le script ci-dessous est déjà complet : copie-le tel quel dans Thonny (ou dans Basthon) pour commencer.
etape0_donnees.py
import numpy as np
import matplotlib.pyplot as plt

# Concentrations en permanganate de potassium (mol/L)
C = np.array([10**-4, 2*10**-4, 4*10**-4, 6*10**-4, 8*10**-4, 10*10**-4,
        20*10**-4, 40*10**-4, 60*10**-4, 80*10**-4, 100*10**-4])
print('C :', C)

# Absorbance mesurée pour chacune de ces concentrations
A = np.array([0.01, 0.02, 0.03, 0.04, 0.06, 0.07, 0.13, 0.25, 0.38, 0.49, 0.63])
print('A :', A)
Résultat attendu

Deux tableaux de 11 valeurs chacun s'affichent dans la console : les concentrations, de 0,0001 à 0,01 mol/L, et les absorbances associées, de 0,01 à 0,63.

01

Tracer l'absorbance en fonction de la concentration

Consigne
  • Trace A en fonction de C, avec des marqueurs carrés ('s') et la légende "A=f(C)".
  • Ajoute une grille, les étiquettes "concentration" / "Absorbance", la légende, et le titre " Evolution de l absorbance avec la concentration".
etape1_trace.py
plt.grid()
# TODO : trace A en fonction de C, marqueurs carrés
plt.plot(_, _, '_', label="______")
plt.xlabel("_____________")
plt.ylabel("__________")
plt.legend()
plt.title("_________________________________________")
plt.show()
Résultat attendu

Un nuage de points qui s'aligne remarquablement bien sur une droite passant par l'origine : un premier indice visuel en faveur de la loi de Beer-Lambert, qui prédit une relation linéaire entre absorbance et concentration.

02

Modéliser automatiquement

Consigne
  • Utilise np.polyfit(C, A, 1) pour trouver automatiquement la droite qui passe au mieux par ce nuage de points, et affiche le résultat.
etape2_modelisation.py
# TODO : trouve le meilleur polynôme du premier degré qui colle aux points expérimentaux
mod = np.polyfit(_, _, _)
print('mod :', mod)
Indice

mod[0] est le coefficient directeur (la pente) de la droite modèle : c'est lui qui, en spectrophotométrie, est directement lié au coefficient d'absorption molaire de l'espèce colorée.

Résultat attendu

mod : [6.17394528e+01 6.03855565e-03] : une pente d'environ 61,7 et une ordonnée à l'origine quasi nulle (0,006) — cohérent avec une droite qui passe presque par l'origine, comme le prédit la théorie.

03

Construire le tableau des valeurs modèles

Consigne
  • Pour pouvoir tracer la droite modèle, il faut calculer la valeur qu'elle prédit pour chaque concentration de C. Crée une liste vide model, puis remplis-la avec une boucle for i in C :, en ajoutant à chaque tour la valeur mod[0]*i + mod[1].
etape3_tableau_modele.py
# TODO : tableau vide, puis rempli valeur par valeur
model = __
for i in _ :
    model.append(mod[_]*i + mod[_])
Résultat attendu

Aucun affichage direct, mais model contient désormais 11 valeurs, une pour chaque concentration de C — prêtes à être tracées à l'étape suivante.

04

Superposer modèle et mesures

Consigne
  • Trace model en fonction de C (ligne rouge, 'r-'), puis superpose à nouveau les points mesurés A en fonction de C (marqueurs carrés).
  • Ajoute grille, étiquettes, légende, et le titre "loi de Beer-Lambert".
etape4_superposition.py
plt.plot(_, _____, '__')
plt.grid()
plt.plot(_, _, '_', label="______")
plt.xlabel("_____________")
plt.ylabel("__________")
plt.legend()
plt.title("________________")
plt.show()
Résultat attendu

La droite rouge du modèle passe remarquablement près de tous les points mesurés : la loi de Beer-Lambert semble bien décrire ces données. Le coefficient d'absorption molaire de l'espèce colorée peut maintenant être évalué à partir de la pente mod[0] obtenue.

05

Et à des concentrations plus élevées ?

À savoir
  • Reprends l'expérience, cette fois avec des concentrations nettement plus fortes (exprimées ici en unités relatives à une concentration de référence C0 = 1).
  • Le script ci-dessous est déjà complet : copie-le tel quel pour continuer.
etape5_concentrations_elevees.py
C0 = 1
c2 = np.array([0, C0/5, C0/2.5, C0/1.67, C0/1.25, C0])
A2 = np.array([0, 0.40, 0.81, 1.11, 1.39, 1.65])

plt.grid()
plt.plot(c2, A2, 'rs', label="A=f(C)")
plt.xlabel("concentration")
plt.ylabel("Absorbance")
plt.legend()
plt.title(" Evolution de l absorbance pour des concentrations importantes")
plt.show()
Résultat attendu

Cette fois, les points mesurés ne s'alignent plus du tout sur une droite : la courbe s'incurve nettement vers le bas à mesure que la concentration augmente. La linéarité observée précédemment ne semble plus être au rendez-vous.

06

Matérialiser l'écart au modèle linéaire

Consigne
  • Pour bien visualiser l'écart, modélise séparément deux sous-ensembles de points par une droite : d'abord les 4 premiers points (en retirant les 2 derniers avec c2[:-2]), puis seulement les 3 premiers (en retirant les 3 derniers avec c2[:-3]).
  • Pour chacun des deux modèles, construis le tableau des valeurs prédites sur toute la plage de c2 (pas seulement sur le sous-ensemble utilisé pour l'ajustement), avec une boucle for i in c2 :.
  • Trace enfin les points mesurés et les deux droites modèles sur le même graphe, avec une légende qui les distingue clairement.
etape6_mise_en_defaut.py
# TODO : modèle à partir des 4 premiers points seulement
c3 = c2[:__]
A3 = A2[:__]
mod3 = np.polyfit(__, __, 1)
model3 = []

# TODO : modèle à partir des 3 premiers points seulement
c4 = c2[:__]
A4 = A2[:__]
mod4 = np.polyfit(__, __, 1)
model4 = []

# TODO : les deux modèles sont évalués sur toute la plage de c2
for i in __ :
    model3.append(mod3[0]*i + mod3[1])
for i in __ :
    model4.append(mod4[_]*i + mod4[_])

plt.grid()
plt.plot(c2, A2, 'rs', label="A=f(C)")
plt.plot(__, ______, 'b-', label="Beer Lambert pour les 4 concentrations les plus faibles")
plt.plot(__, ______, 'k-', label="Beer Lambert pour les 3 concentrations les plus faibles")
plt.xlabel("concentration")
plt.ylabel("Absorbance")
plt.legend()
plt.title(" Evolution de l absorbance pour des concentrations importantes")
plt.show()
Indice

c2[:-2] retire les 2 derniers éléments d'un tableau de 6 valeurs, ce qui en garde 4 ; c2[:-3] en retire 3, ce qui n'en garde que 3. Les boucles for, elles, parcourent toujours c2 en entier : c'est la différence entre les données utilisées pour ajuster le modèle et la plage sur laquelle on l'évalue ensuite.

Résultat attendu

Les deux droites modèles (bleue et noire) se ressemblent pour les faibles concentrations, mais s'écartent nettement des points mesurés (carrés rouges) dès que la concentration dépasse environ 0,4 : la loi de Beer-Lambert, pourtant bien vérifiée à faible concentration, cesse d'être valable ici.

+

Conclusion

À retenir
  • L'invalidité de la loi de Beer-Lambert pour des concentrations élevées est ici clairement démontrée : un modèle qui fonctionne parfaitement dans un certain domaine peut totalement échouer en dehors de celui-ci.
  • C'est une leçon générale en physique-chimie : toute loi ou tout modèle a un domaine de validité, qu'il est indispensable de vérifier avant de l'appliquer aveuglément. Ici, ce domaine correspond aux solutions diluées — au-delà, des phénomènes supplémentaires (interactions entre espèces dissoutes, saturation du détecteur…) viennent perturber la relation linéaire idéale.

Pense-bête — tester le domaine de validité d'un modèle

np.polyfit(x,y,1)modélise par une droite affine
liste.append(v)construit un tableau valeur par valeur
c2[:-n]retire les n derniers éléments
ajuster sur un sous-ensemblepolyfit sur des données restreintes
évaluer sur toute la plageboucle for sur le tableau complet
domaine de validitéplage où le modèle reste fiable

Pas de Thonny sous la main ? Utilise Basthon

Ouvrir dans un nouvel onglet ↗
Basthon est une console Python qui tourne directement dans le navigateur, sans rien installer. Colle ici (avec Ctrl+V ou Cmd+V) le code copié avec les boutons « Copier le code » ci-dessus, puis appuie sur Entrée pour l'exécuter.