"""Constructed lung-volume spirogram and endpoint ledger. Python 3.14, NumPy 2.3.5, Matplotlib 3.10.7. Run in _media; output PNG in cwd. Absolute volume is stipulated: spirometry alone does not determine the RV offset. """ from pathlib import Path import matplotlib matplotlib.use('Agg') import matplotlib.pyplot as plt import numpy as np rv, frc, vt, tlc = 1.4, 2.5, .5, 6.0 assert abs((tlc-rv)-(3.0+.5+1.1))<1e-12 fig, (ax, ledger) = plt.subplots(1, 2, figsize=(9, 5), dpi=100, gridspec_kw={'width_ratios':[1.45, 1]}, facecolor='white') t0=np.linspace(0, 6, 301);v0=frc+vt*(1-np.cos(np.pi*t0))/2 # Quiet breaths end at FRC; smooth maximal inspiration, full expiration, recovery. t1=np.linspace(6, 8, 101);v1=frc+(tlc-frc)*(1-np.cos(np.pi*(t1-6)/2))/2 t2=np.linspace(8, 11, 151);v2=tlc-(tlc-rv)*(1-np.cos(np.pi*(t2-8)/3))/2 t3=np.linspace(11, 13, 101);v3=rv+(frc-rv)*(1-np.cos(np.pi*(t3-11)/2))/2 ax.plot(np.r_[t0,t1,t2,t3],np.r_[v0,v1,v2,v3],color='#246b91',lw=2.2) levels=[(rv,'RV = 1.4 L'),(frc,'FRC = 2.5 L'),(frc+vt,'End-tidal inspiration = 3.0 L'),(tlc,'TLC = 6.0 L')] for y,label in levels: ax.axhline(y,ls=':',color='#9a9a9a',lw=.8) ax.set(xlim=(0,13.2),ylim=(0,6.5),xlabel='Illustrative time (s)',ylabel='Stipulated lung-gas volume (L)') ax.text(2.4,3.35,'Quiet tidal breaths',fontsize=9,ha='center') ax.text(8,6.17,'Maximal inspiration',fontsize=9,ha='center') ax.text(11,1.10,'Maximal expiration',fontsize=9,ha='center') ax.spines[['top','right']].set_visible(False) ledger.set(xlim=(-.2,5.5),ylim=(0,6.5));ledger.axis('off') for y,label in levels: ledger.hlines(y,-.1,5.1,color='#b0b0b0',ls=':',lw=.8) ledger.text(-.1,y+.08,label,fontsize=8,color='#555555') segments=[(.25,0,rv,'RV\n1.4 L','#66757f'),(1.25,rv,frc,'ERV\n1.1 L','#287c5d'), (1.25,frc,frc+vt,'VT 0.5 L','#a26726'),(1.25,frc+vt,tlc,'IRV\n3.0 L','#246b91'), (3.0,frc,tlc,'IC\n3.5 L','#704795'),(4.35,rv,tlc,'VC\n4.6 L','#9b4545')] for x,a,b,label,color in segments: ledger.annotate('',xy=(x,b),xytext=(x,a),arrowprops=dict(arrowstyle='<->',lw=1.6,color=color)) ledger.text(x+.13,(a+b)/2,label,va='center',fontsize=9,color=color) fig.suptitle('Lung-volume subdivisions: the endpoints define the quantity',fontsize=13) fig.text(.5,.035,'Constructed values, not reference limits. The absolute residual-volume offset requires an independent measurement.',ha='center',fontsize=9) fig.subplots_adjust(left=.075,right=.98,bottom=.17,top=.85,wspace=.24) fig.savefig(Path('lung-volume-subdivisions.png'),facecolor='white',dpi=100) plt.close(fig)