Taux de dissociation d’un acide

Où l’on visualise comment varie le taux de dissociation d’un acide avec sa concentration molaire et son pKa.

Le taux de dissociation d’un acide dépend à la fois du pKa de l’acide et de la concentration apportée C de l’acide :

Le graphique suivant permet d’apprécier les variations du taux de dissociation selon ces deux paramètres :

Commentaires en chimie :

La concentration est en échelle logarithmique afin de voir l’effet des très faibles concentrations.

Pour une valeur de pKa donnée, plus C diminue plus le taux de dissociation augmente : la dilution a pour effet de favoriser la dissociation.

Pour une concentration donnée, plus le pKa diminue plus l’acide est dissocié.

On associe généralement les acides forts à un pKa inférieur à 2-3 et à un faible taux de dissociation ; cependant à très faible concentration on constate que le taux de dissociation peut être très élevé.


Commentaires sur le code Python qui génère ce graphe :

Ce code nécessite les bibliothèques suivantes :

from math import sqrt
import matplotlib.pyplot as plt
import numpy as np
import matplotlib as mpl#Normalisation des valeurs
import matplotlib.colorbar as cbar#barres de couleurs
from mpl_toolkits.axes_grid1 import make_axes_locatable#positionner les barres de couleurs

Je définis une fonction qui calcule le taux pour un pKa et une concentration donnés :

def alpha(pKa,C):
    """
    renvoie le taux de dissociation en %
    """
    Ka = pow(10,-pKa)
    a = C
    b = Ka
    c = -Ka
    delta = b**2-4*a*c
    x = (-b+sqrt(delta))/(2*a)*100
    return x

Les valeurs de pKa et de concentration étant contenues dans des listes, il faut vectoriser cette fonction afin qu’elle accepte des listes en argument :

alpha_vect = np.vectorize(alpha)

Sur le graphique, les courbes des pKa très élevés (10 à 14) sont presque confondues ; aussi je me suis arrêté à pKa=9 car on comprend la tendance des courbes. Ce paramètre peut être modifié.

L’utilisation d’un colormap remplace avantageusement une légende sur le graphique : d’une part la place manque, d’autre part, l’évolution des couleurs montre le sens d’évolution des courbes. Le code complet :

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Créé le Thu Jan 19 17:03:00 2023

@auteur: David ALBERTO
(www.astrolabe-science.fr)
"""
from math import sqrt
import matplotlib.pyplot as plt
import numpy as np
import matplotlib as mpl#Normalisation des valeurs
import matplotlib.colorbar as cbar#barres de couleurs
from mpl_toolkits.axes_grid1 import make_axes_locatable#positionner les barres de couleurs

plt.rcParams["font.family"] = "Linux Libertine O" # ou autre police installée
plt.rcParams["font.size"] = 8

liste_logC = np.linspace(-6, -1,50)
liste_C = [pow(10,logC) for logC in liste_logC]
pKa_max = 9 # pKa maximal (pKa de 0 à pKa_max)
liste_pKa = np.linspace(0,pKa_max,pKa_max+1)
# -----------------------------------------

def alpha(pKa,C):
    """
    renvoie le taux de dissociation en %
    """
    Ka = pow(10,-pKa)
    a = C
    b = Ka
    c = -Ka
    delta = b**2-4*a*c
    x = (-b+sqrt(delta))/(2*a)*100
    return x

alpha_vect = np.vectorize(alpha)# vectorisation de la fonction, pour qu'elle accepte des listes de valeurs en argument
# ----------------
# Colormap :
#gamme de couleurs choisie (colormap) :
cmap=plt.get_cmap('brg',pKa_max)
"""
quelques colormaps :
'Greys', 'Purples', 'Blues', 'Greens', 'Oranges', 'Reds',
'YlOrBr', 'YlOrRd', 'OrRd', 'PuRd', 'RdPu', 'BuPu',
'GnBu', 'PuBu', 'YlGnBu', 'PuBuGn', 'BuGn', 'YlGn',
'cool','winter','gnuplot','brg'
"""
#normalisation de la gamme de valeurs :
norm = mpl.colors.Normalize(vmin=min(liste_pKa),vmax=max(liste_pKa))
# ----------------


fig = plt.figure(figsize=(6,4),tight_layout=True)

plt.suptitle("taux de dissociation d'un acide",y=0.95,fontsize=12)
ax1 = plt.subplot(111)
ax1.set_xlabel("C (mol/L)")
ax1.set_xlim(min(liste_C),max(liste_C))
ax1.set_xscale('log')
ax1.set_ylabel(r"$\alpha$/%",loc='top',rotation=0,va='top')
ax1.set_yticks(np.arange(0,100,10))
ax1.set_ylim(0,100)
ax1.yaxis.set_label_coords(-0.008, 1.02)# décale l'étiquette
ax1.xaxis.set_label_coords(0.50, -.035)# décale l'étiquette

ax1.grid(which='both',lw=0.25)
# ----------------------------------------------
#  tracé des courbes :

for pKa in liste_pKa:
    liste_alpha = alpha_vect(pKa, liste_C)
    ax1.plot(liste_C,liste_alpha,c=cmap(norm(pKa)),lw=1)

# ----------------------------------------------
#tracé de la barre de couleurs :
divider = make_axes_locatable(ax1)
cax = divider.append_axes('bottom', size='3%', pad=0.3)
cb=cbar.ColorbarBase(cax, cmap=cmap, norm=norm, orientation='horizontal')
cax.set_xlabel(r'$pK_a$')
cax.set_xticks(np.arange(0,pKa_max,1))
cax.xaxis.set_label_coords(0.98, -0.50)# décale l'étiquette
# ----------------------------------------------
fig.text(0.975,0.2,"D. Alberto (www.astrolabe-science.fr)",
         transform=fig.transFigure,
         rotation=90,fontsize=6,color='gray')

fig.savefig("taux_dissociation.pdf")
fig.savefig("taux_dissociation.png",dpi=300)

Le code à télécharger (compressé) :


Tracé du graphique avec LaTeX :

La première option serait de créer des fonctions réalisant les calculs de taux de dissociation similaires à ceux faits avec Python. Cependant, la syntaxe LaTeX étant moins souple d’utilisation pour des calculs complexes (ce n’est d’ailleurs pas la raison d’être de LaTeX), il faut définir plusieurs fonctions. Après l’avoir fait, j’ai constaté que les capacités de calcul de LaTeX atteignaient leur limite pour de faibles pKa (<4) et de faibles concentrations (<1e-4). Les courbes se déformaient.

Je me suis donc rabattu sur le passage par un fichier csv externe où sont stockées les valeurs calculées avec Python. Le module LaTeX pgfplots peut lire des valeurs dans un fichier externe. J’ai modifié le script Python pour qu’il génère des fichiers csv de 2 colonnes (C, taux) pour chaque valeur de pKa, avec le module Python pandas de gestion de dataframe. Extrait du code Python modifié :

#  tracé des courbes :

for pKa in liste_pKa:
    liste_alpha = alpha_vect(pKa, liste_C)
    ax1.plot(liste_C,liste_alpha,c=cmap(norm(pKa)),lw=1)
    df = pd.DataFrame({'C' : liste_C,
                       'alpha' : liste_alpha,
                       })
    df.to_csv('pKa-' + str(pKa) + '.csv',index=False)

Dans la boucle parcourant les valeurs de pKa, le tableau est nommé df ; il a pour colonnes ‘C’ et ‘alpha’. À chaque itération, un fichier csv est créé, nommé ‘pKa-str(pKa)’.

Le graphique LaTeX donne :

\documentclass[border=0.5cm,10pt,convert={ghostscript,outext=.png,density=800x800}]{standalone}%conversion en png avec ghostscript

%COMPILé AVEC XeLaTeX

\usepackage[T1]{fontenc}
\usepackage[dvipsnames,svgnames]{xcolor}
\usepackage{lmodern}
\usepackage{fontspec}
\usepackage{tikz}
\usepackage{pgfplots}\pgfplotsset{compat=newest}
\pgfplotsset{major grid style={gray},
grid,grid=both,
axis line shift=2pt,
xtick align=outside,
ytick align=outside,
tickpos=left,
}

\setmainfont{Linux Libertine O}

\begin{document}

\footnotesize

\begin{tikzpicture}
\tikzset{every plot/.style={line width=1pt,no marks,}}

\begin{semilogxaxis}
[xmin=1e-6,xmax=1e-1,
ymin=0,ymax=100,
minor y tick num=1,
xlabel=concentration (mol/L),
title=taux de dissociation d'un acide,
colormap name=viridis,
cycle list ={[samples of colormap={10} of viridis]},
legend pos=outer north east,
legend style={line width=1pt,
line width=1pt,
},
]
\addlegendimage{empty legend}
\addplot table [col sep=comma]{pKa-0.0.csv};
\addplot table [col sep=comma]{pKa-1.0.csv};
\addplot table [col sep=comma]{pKa-2.0.csv};
\addplot table [col sep=comma]{pKa-3.0.csv};
\addplot table [col sep=comma]{pKa-4.0.csv};
\addplot table [col sep=comma]{pKa-5.0.csv};
\addplot table [col sep=comma]{pKa-6.0.csv};
\addplot table [col sep=comma]{pKa-7.0.csv};
\addplot table [col sep=comma]{pKa-8.0.csv};
\addplot table [col sep=comma]{pKa-9.0.csv};
%
\addlegendentry{\hspace{-5mm}$ pK_A $}
\addlegendentry{0}
\addlegendentry{1}
\addlegendentry{2}
\addlegendentry{3}
\addlegendentry{4}
\addlegendentry{5}
\addlegendentry{6}
\addlegendentry{7}
\addlegendentry{8}
\addlegendentry{9}
\end{semilogxaxis}
\end{tikzpicture}
\end{document}

Soyez le premier à commenter

Laisser un commentaire