codexandrews-carbon-dioxide-critical-apparatus.py
andrews-carbon-dioxide-critical-apparatus.py
"""Functional schematic based on Andrews (1869), pp. 576–583 and Plate LXIII.
Original diagram, not a scale reconstruction or digitization of the historical plate.
Python 3.14; Matplotlib 3.10. Run from _media with MPLBACKEND=Agg.
"""
from pathlib import Path
import matplotlib.pyplot as plt
from matplotlib.patches import Rectangle
BLUE = '#176baa'
GRAY = '#7f8791'
def sample(ax, x, bottom, top, split=None):
ax.add_patch(Rectangle((x, bottom), .58, top-bottom, facecolor='#fff7e5',
edgecolor='#333333', lw=1.5))
if split is not None:
ax.add_patch(Rectangle((x+.015, bottom), .55, split-bottom,
facecolor='#7dc5e7', edgecolor='none'))
ax.plot([x+.02, x+.56], [split, split], color=BLUE, lw=2)
def main():
plt.rcParams.update({'font.size': 10, 'figure.facecolor': 'white'})
fig, (app, infer) = plt.subplots(1, 2, figsize=(11, 5.5),
gridspec_kw={'width_ratios': [1.25, 1]}, layout='constrained')
app.set(xlim=(0, 7.1), ylim=(0, 7.7))
app.axis('off')
app.set_title('Control and readout: coupled pressure apparatus', fontsize=11, pad=12)
# Two pressure bodies joined by a water-filled manifold.
for x in (1.25, 4.75):
app.add_patch(Rectangle((x-.32, 1.15), 1.22, 1.9, facecolor='#dbeef8',
edgecolor='#855c3b', lw=3))
app.add_patch(Rectangle((x, 2.35), .58, 3.65, facecolor='white',
edgecolor='#333333', lw=1.5))
app.add_patch(Rectangle((x+.02, 2.35), .54, 1.2, facecolor=GRAY, edgecolor='none'))
app.add_patch(Rectangle((x-.22, 3.25), 1.02, 3, facecolor='#dbeef8',
edgecolor=BLUE, alpha=.45))
app.add_patch(Rectangle((x+.19, .5), .2, 1.45, facecolor='#555555', edgecolor='black'))
app.plot([x-.05, x+.63], [.5, .5], color='#333333', lw=4)
app.annotate('', xy=(x+.29, 1.55), xytext=(x+.29, .72),
arrowprops={'arrowstyle': '->', 'lw': 1.6, 'color': 'black'})
app.plot([2.15, 4.43], [1.8, 1.8], color='#855c3b', lw=13, solid_capstyle='butt')
app.plot([2.15, 4.43], [1.8, 1.8], color='#dbeef8', lw=7, solid_capstyle='butt')
sample(app, 1.25, 3.55, 6, split=4.35)
sample(app, 4.75, 3.55, 6)
app.text(1.54, 6.6, 'CO₂ sample', ha='center', weight='bold')
app.text(5.04, 6.6, 'Air gauge', ha='center', weight='bold')
app.text(3.25, .15, 'Steel screws compress the water', ha='center')
app.text(3.3, 1.04, 'Shared water\npressure circuit', ha='center', fontsize=9)
app.annotate('Mercury transmits\nthe load', xy=(1.52, 2.8), xytext=(2.7, 2.8),
fontsize=9, arrowprops={'arrowstyle': '->', 'color': GRAY})
app.annotate('Flowing-water jackets\nset temperatures separately', xy=(4.55, 5.4),
xytext=(3.5, 7.1), ha='center', fontsize=9,
arrowprops={'arrowstyle': '->', 'color': BLUE})
app.annotate('Optical column readings\n→ calibrated volumes', xy=(1.55, 5),
xytext=(2.7, 4.3), fontsize=9,
arrowprops={'arrowstyle': '->', 'color': '#333333'})
infer.set(xlim=(0, 6), ylim=(0, 7.7))
infer.axis('off')
infer.set_title('What the observations distinguish', fontsize=11, pad=12)
sample(infer, .8, 4.1, 6.4, split=5.15)
infer.text(2.05, 6.1, 'Below Tc', weight='bold')
infer.text(2.05, 5.65, 'Gas and liquid coexist')
infer.text(2.05, 5.05, 'Visible meniscus', color=BLUE)
infer.annotate('', xy=(1.45, 5.15), xytext=(1.95, 5.15),
arrowprops={'arrowstyle': '->', 'color': BLUE})
sample(infer, .8, .95, 3.25)
infer.add_patch(Rectangle((.815, .95), .55, 2.3, facecolor='#bdddec', edgecolor='none'))
infer.text(2.05, 2.95, 'Above Tc', weight='bold')
infer.text(2.05, 2.4, 'One fluid phase')
infer.text(2.05, 1.85, 'Compression can raise density\nwithout a phase boundary')
infer.text(3, .12, 'No meniscus alone is insufficient:\na subcritical phase can also run out.',
ha='center', color='#555555', fontsize=9)
fig.suptitle('Andrews’s 1869 carbon dioxide experiment — functional schematic', fontsize=13)
fig.savefig(Path(__file__).stem + '.png', dpi=120, facecolor='white')
plt.close(fig)
if __name__ == '__main__':
main()