codexglobin-assembly-stoichiometry.py
globin-assembly-stoichiometry.py
"""Ideal alpha/beta/gamma-chain stoichiometry; not an intracellular assembly model.
Python 3.14; NumPy 2.3.5; Matplotlib 3.10.7.
"""
from pathlib import Path
import numpy as np
import matplotlib
matplotlib.use('Agg')
import matplotlib.pyplot as plt
from matplotlib.patches import Polygon
def feasible(hba, hbf):
return (hba >= 0) & (hbf >= 0) & (hba <= 40) & (hbf <= 30) & (hba + hbf <= 50)
def main():
fig, ax = plt.subplots(figsize=(7.2, 4.8), dpi=100, facecolor='white')
ax.set_facecolor('white')
x = np.linspace(0, 50, 501)
ax.add_patch(Polygon([(0,0),(40,0),(40,10),(20,30),(0,30)], closed=True,
color='#9dc9d4', alpha=0.65, label='Stoichiometrically feasible'))
ax.plot(x, 50-x, lw=2.2, color='#225d9a', label='Alpha-chain limit: HbA + HbF ≤ 50')
ax.axvline(40, lw=1.7, ls='--', color='#ad5628', label='Beta-chain limit: HbA ≤ 40')
ax.axhline(30, lw=1.7, ls=':', color='#795394', label='Gamma-chain limit: HbF ≤ 30')
ax.set(xlim=(0,50), ylim=(0,50), xlabel='Hemoglobin A tetramers (pmol)',
ylabel='Fetal hemoglobin tetramers (pmol)', title='Shared alpha chains constrain two tetramer products')
ax.grid(alpha=0.15)
ax.legend(loc='upper right', fontsize=8)
fig.text(0.5, 0.015, 'Original ideal model: 100 pmol alpha, 80 pmol beta, 60 pmol gamma; no losses or other assemblies.',
ha='center', fontsize=8)
fig.tight_layout(rect=(0,0.035,1,1))
fig.savefig(Path('globin-assembly-stoichiometry.png'), facecolor='white')
plt.close(fig)
if __name__ == '__main__':
main()