Courbe de titrage conductimétrique-Python

Tracé automatique à partir des données, avec détermination du point équivalent.

Sur un graphique représentant la conductivité en fonction du volume de solution titrante versée, l’équivalence d’un titrage conductimétrique est repérée par un changement d’inclinaison des points de mesure.

Si on place dans un fichier .csv les coordonnées des points (V, conductivite), le script Python suivant importe les valeurs du fichier et trace le graphique suivant :

Le script s’appuie sur une valeur de volume comprise entre les deux portions de droites (valeur entrée par l’utilisateur dans le code) pour calculer les deux droites de régression linéaire correspondantes, calculer les coordonnées de leur intersection, et afficher le volume du point équivalent.

Les modules Python utilisés : matplotlib (tracé de graphes), numpy (régression linéaire) et pandas (import de données et gestion de tableaux de valeurs).

Le fichier .csv :

Le script Python :

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Créé le Mon Feb  6 18:00:08 2023

@auteur: david ALBERTO
(www.astrolabe-science.fr)
"""
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
import locale


#  ----------------------
locale.setlocale(locale.LC_NUMERIC, 'fr_FR.UTF-8')# format numérique
plt.rcParams['axes.formatter.use_locale'] = True

V_seuil = 10 # volume séparant les deux parties de la courbe

prop_points = dict(color='C0',s=15)# style des points
prop_segments = dict(color='orangered',lw=0.6)# style des segments


plt.rcParams["font.family"] = "Roboto"

#  importation des données du fichier csv :----------------------
table = pd.read_csv("titrageCondNH3.csv",sep='\t', comment='#')

debut = table[table["volume"] <= V_seuil]
fin = table[table["volume"] > V_seuil]

def regr_lin(data):
    """
    à partir d'un DataFrame ''data', calcule et renvoie les coeff d'une régression linéaire
    """
    X = data['volume']
    Y = data['conductance']
    
    fit=np.polyfit(X, Y, 1)
    pente=fit[0]
    ordonnee=fit[1]
    return pente, ordonnee

def intersection(debut,fin):
    """
    calcule les coordonnées de l'intersection des segments,
    et affiche le pt d'intersection.
    """
    a1, b1 = regr_lin(debut)
    a2, b2 = regr_lin(fin)
    #  volumes min et max :
    Xmin = min(debut['volume'])
    Xmax = max(fin['volume'])

    # Coordonnées de l'intersection des segments
    X0 = (b2-b1)/(a1-a2)
    Y0 = a1*X0 + b1

    #  tracé des segments :
    axe.plot([Xmin,X0+1],[a1*Xmin+b1,a1*(X0+1)+b1],**prop_segments)
    axe.plot([X0-1,Xmax],[a2*(X0-1)+b2,a2*Xmax+b2],**prop_segments)

    #  tracé de l'intersection :
    axe.scatter(X0,Y0,s=50,marker='+',color='black')
    axe.plot([X0,X0],[Y0,ymin],'--',c='gray',lw=0.9) # pointillés
    axe.text(0.99,0.02,f' {X0:.1f} mL',ha='right',c='gray',fontweight='bold',
             transform=axe.transAxes)


#  paramètre du graphe :-------------------------

fig = plt.figure(figsize=(6,4),tight_layout=True)
axe = plt.subplot(111)
axe.set_xlabel("V (mL)")
axe.set_ylabel(r"conductivité $\sigma$ (mS/cm)")

axe.set_title("titrage conductimétrique d'une solution d'ammoniaque")

axe.text(0.01,0.99,"prise d'essai : 20 mL\nsolution titrante HCl 0,100 mol/L ",
         transform=axe.transAxes,
         va='top'
         # ,ha='right'
         )

# ----------------------------------

for donnees in [debut, fin]:
    V = donnees['volume']
    Cond = donnees['conductance']
    axe.scatter(V,Cond,**prop_points)

ymin,ymax = axe.get_ylim()
axe.set_ylim(ymin,ymax)

intersection(debut, fin)

fig.savefig('titrageConducti_NH3.png',dpi=300)
fig.savefig('titrageConducti_NH3.pdf')

Remarque concernant l’allure de la courbe de titrage des sulfates par l’ion baryum :

La comparaison des conductivités molaires des ions mis en jeu prévoit une diminution de la conductivité avant l’équivalence, alors que les courbes expérimentales montrent une soit une augmentation soit une absence de variation de la conductivité. J’ai déjà vu dans un manuel scolaire de lycée une courbe décroissante au début (allure démentie par l’expérience). Professeur.es : attention aux choix de vos exemples en cours/exercices/évaluations !

L’interprétation pourrait se trouver du côté de la formation de paires d’ions en solution ; cette interprétation est présentée dans un article de Stéphan LAMPERT dans le BUP n°892 de mars 2007.

5 Comments

  1. David ALBERTO said:

    Bonjour,
    Malheureusement, je n’ai pas les données du titrage des chlorures dans Hépar. Il s’agissait en fait du titrage des sulfates, j’ai corrigé le graphique sur la page web. Désolé pour la confusion. J’aurai peut-être l’occasion de faire le titrage des Cl- dans Hépar cette année ; le cas échéant, je publierai les données sur cette même page.
    Cordialement,
    David

    15 août 2023
  2. Asolectine said:

    Bonjour,
    Le fichier CSV du titrage d’hépar ne correspond pas à l’image affichée. Pourriez-vous mettre en ligne les données du titrage de CL- de hépar? merci

    15 août 2023
  3. SARKISSIAN said:

    Je découvre et apprend python grâce à vos scripts. Merci infiniment pour les partages !

    5 août 2023
  4. David ALBERTO said:

    Oui, merci pour votre remarque. Je vais rectifier le texte. Quant à préciser pour quelle solution l’allure prévue de la courbe est différente de celle obtenue expérimentalement, je renvoie à la lecture de l’article.

    10 février 2023
  5. Millet said:

    Bonjour,
    Votre commentaire est adéquat, mais il y a peut-être un lapsus : “courbes expérimentales … augmentation” “courbe croissante … démentie par l’expérience”.
    D’autre part, sans précision sur la solution, la courbe peut être croissante ou décroissante (cf. article de Stéphan Lambert)

    10 février 2023

Laisser un commentaire