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).
Les données
- On étudie l'absorbance
Ad'une solution de permanganate de potassium (un colorant violet) mesurée au spectrophotomètre, pour 11 concentrationsCdifférentes (en mol/L). - Le script ci-dessous est déjà complet : copie-le tel quel dans Thonny (ou dans Basthon) pour commencer.
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)
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.
Tracer l'absorbance en fonction de la concentration
- Trace
Aen fonction deC, 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".
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()
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.
Modéliser automatiquement
- 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.
# 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.
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.
Construire le tableau des valeurs modèles
- 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 videmodel, puis remplis-la avec une bouclefor i in C :, en ajoutant à chaque tour la valeurmod[0]*i + mod[1].
# TODO : tableau vide, puis rempli valeur par valeur
model = __
for i in _ :
model.append(mod[_]*i + mod[_])
Aucun affichage direct, mais model contient désormais 11 valeurs, une pour chaque concentration de C — prêtes à être tracées à l'étape suivante.
Superposer modèle et mesures
- Trace
modelen fonction deC(ligne rouge,'r-'), puis superpose à nouveau les points mesurésAen fonction deC(marqueurs carrés). - Ajoute grille, étiquettes, légende, et le titre
"loi de Beer-Lambert".
plt.plot(_, _____, '__')
plt.grid()
plt.plot(_, _, '_', label="______")
plt.xlabel("_____________")
plt.ylabel("__________")
plt.legend()
plt.title("________________")
plt.show()
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.
Et à des concentrations plus élevées ?
- 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.
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()
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.
Matérialiser l'écart au modèle linéaire
- 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 avecc2[:-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 bouclefor 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.
# 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.
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
- 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-ensemble | polyfit sur des données restreintes |
| évaluer sur toute la plage | boucle 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 ↗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.