pH roztoků NaOH na základě molarity
Při práci s chemickými koncentracemi často logaritmická povaha pH škály ztěžuje vizualizaci dat. Pokud vykreslíte pH proti molaritě na standardní lineární stupnici, získáte křivku ve tvaru “hokejky”, která maskuje proporcionální vztah iontů.
V tomto příspěvku použijeme Python a matplotlib pro vizualizaci pH hydroxidu sodného (NaOH) od 0 až po vysoce koncentrovaný 3 molární roztok, přičemž porovnáme lineární a logaritmickou stupnici, abychom zjistili, která poskytuje lepší vhled.
Chemická logika
Jelikož je NaOH silná zásada, zcela disociuje. Pro přesný výpočet pH v širokém rozsahu — zvláště když překročíme 1.0M — nejprve vypočítáme pOH:
$$pOH = -\log_{10}[OH^-]$$$$pH = 14 - pOH$$Zajímavé je, že při 3M NaOH je pOH záporné ($\approx -0.48$), což znamená, že pH se ve skutečnosti zvýší na 14.48, čímž se porušuje běžné učebnicové pravidlo “0 až 14”.
Implementace v Pythonu
Používáme numpy pro generování rozsahů koncentrací a matplotlib.pyplot se stylem ggplot pro čistý, profesionální vzhled. Všimněte si, že generujeme dva samostatné grafy pro zvýraznění různých perspektiv.
#!/usr/bin/env python3
# SPDX-License-Identifier: CC0-1.0
import numpy as np
import matplotlib.pyplot as plt
# Nastavení stylu na ggplot
plt.style.use('ggplot')
def calculate_ph(molarity):
"""Vypočítá pH pro danou molaritu NaOH včetně autoionizace vody."""
kw = 1e-14
# Kvadratické řešení pro [OH-] pro přesné zpracování nízkých koncentrací
oh_conc = (molarity + np.sqrt(molarity**2 + 4 * kw)) / 2
poh = -np.log10(oh_conc)
return 14 - poh
# Data pro lineární graf (0 až 3M)
x_linear = np.linspace(0, 3, 1000)
y_linear = calculate_ph(x_linear)
# Data pro logaritmický graf (0.01 až 3M)
# Použití logspace zajišťuje plynulé vykreslení na logaritmické stupnici
x_log = np.logspace(np.log10(0.01), np.log10(3), 1000)
y_log = calculate_ph(x_log)
# Vytvoření lineárního grafu
plt.figure(figsize=(10, 6))
plt.plot(x_linear, y_linear, color='#E24A33', linewidth=2.5, label='pH Value')
plt.title('pH of NaOH Solution (Linear Scale: 0M to 3M)', fontsize=14, fontweight='bold')
plt.xlabel('Molarity of NaOH (mol/L)', fontsize=12)
plt.ylabel('pH', fontsize=12)
plt.ylim(7, 15)
plt.grid(True, linestyle='--', alpha=0.7)
plt.legend()
plt.tight_layout()
plt.savefig('ph_linear_scale.png', dpi=300)
plt.close()
# Vytvoření logaritmického grafu
plt.figure(figsize=(10, 6))
plt.plot(x_log, y_log, color='#348ABD', linewidth=2.5, label='pH Value')
plt.xscale('log')
plt.title('pH of NaOH Solution (Log Scale: 0.01M to 3M)', fontsize=14, fontweight='bold')
plt.xlabel('Molarity of NaOH (Logarithmic Scale mol/L)', fontsize=12)
plt.ylabel('pH', fontsize=12)
plt.ylim(11.5, 15) # Zaměřený rozsah pro okno 0.01M-3M
plt.grid(True, which="both", linestyle='--', alpha=0.7)
plt.legend()
plt.tight_layout()
plt.savefig('ph_log_scale.png', dpi=300)
plt.close()
# Pro účely systémového požadavku na poskytnutí jediného "main" názvu souboru v tagu
# uložíme také kombinovanou verzi.
fig, (ax1, ax2) = plt.subplots(2, 1, figsize=(10, 12))
# Lineární graf
ax1.plot(x_linear, y_linear, color='#E24A33', linewidth=2.5)
ax1.set_title('Linear Scale (0M to 3M)', fontsize=14, fontweight='bold')
ax1.set_ylabel('pH')
ax1.set_ylim(7, 15)
# Logaritmický graf
ax2.plot(x_log, y_log, color='#348ABD', linewidth=2.5)
ax2.set_xscale('log')
ax2.set_title('Logarithmic Scale (0.01M to 3M)', fontsize=14, fontweight='bold')
ax2.set_xlabel('Molarity of NaOH (mol/L)')
ax2.set_ylabel('pH')
ax2.set_ylim(11.5, 15)
plt.tight_layout()
plt.savefig('pH NaOH molarity.svg', dpi=300)