codex/single-breath-dead-space.py

single-breath-dead-space.py
"""Constructed single-breath tracer curve with a sharp equal-area replacement.
Python 3.14, NumPy 2.3.5, Matplotlib 3.10.7. Run in _media; PNG in cwd.
No measured patient data: transition spans 100-200 mL; equal-area step is 150 mL.
"""
from pathlib import Path
import matplotlib
matplotlib.use('Agg')
import matplotlib.pyplot as plt
import numpy as np

v=np.linspace(0,500,2001)
g=np.clip((v-100)/100,0,1)
area=np.trapezoid(g,v)
assert abs(area-350)<1e-9 and abs(500-area-150)<1e-9
left=(v>=100)&(v<=150);right=(v>=150)&(v<=200)
assert abs(np.trapezoid(g[left],v[left])-12.5)<1e-9
assert abs(np.trapezoid(1-g[right],v[right])-12.5)<1e-9
fig,ax=plt.subplots(figsize=(8,4.5),dpi=100,facecolor='white')
ax.plot(v,g,lw=2.5,color='#276c91',label='Constructed tracer curve')
ax.plot([0,150,150,500],[0,0,1,1],'--',lw=1.7,color='#a34f28',label='Equal-area step')
ax.fill_between(v[left],0,g[left],color='#b7d7e8',label='Equal areas = 12.5 mL each')
ax.fill_between(v[right],g[right],1,color='#e8c6aa')
ax.axvline(150,ymax=.86,color='#777777',ls=':',lw=1)
ax.text(48,1.08,'Phase I',ha='center',fontsize=10)
ax.text(150,1.08,'Phase II',ha='center',fontsize=10)
ax.text(330,1.08,'Phase III',ha='center',fontsize=10)
ax.annotate('First tracer: 100 mL',xy=(100,.01),xytext=(24,.26),fontsize=10,
            arrowprops=dict(arrowstyle='->',color='#555555'))
ax.annotate('Dead-space step: 150 mL',xy=(150,.5),xytext=(245,.54),fontsize=10,
            arrowprops=dict(arrowstyle='->',color='#555555'))
ax.set(xlim=(-5,505),ylim=(-.035,1.17),xlabel='Expired volume (mL)',
       ylabel='Tracer fraction / alveolar plateau fraction')
ax.spines[['top','right']].set_visible(False)
ax.legend(loc='lower right',frameon=False,fontsize=9)
fig.suptitle('A mixing transition shifts the dead-space boundary',fontsize=13)
fig.text(.5,.02,'Ideal illustration: gas fractions and volumes are stipulated, not clinical reference data.',ha='center',fontsize=9)
fig.subplots_adjust(left=.12,right=.97,bottom=.17,top=.85)
fig.savefig(Path('single-breath-dead-space.png'),facecolor='white',dpi=100)
plt.close(fig)