codexargon-mixture-density-and-temperature-confounding.py
argon-mixture-density-and-temperature-confounding.py
"""Plot a chosen ideal binary-mixture model, not historical data; output to CWD."""
from pathlib import Path
import matplotlib
matplotlib.use('Agg')
import matplotlib.pyplot as plt
import numpy as np
def main():
plt.rcParams.update({'font.size':12,'font.family':'DejaVu Sans'})
rgas=8.31446261815324
mn,ma=.028,.040
pressure,volume,temperature=100000.,.002,300.
fraction=.01
mean_molar_mass=(1-fraction)*mn+fraction*ma
density_ratio=mean_molar_mass/mn
colder=temperature/density_ratio
reference_mass=pressure*volume*mn/(rgas*temperature)
mixture_mass=pressure*volume*mean_molar_mass/(rgas*temperature)
colder_mass=pressure*volume*mn/(rgas*colder)
assert abs(mixture_mass-colder_mass)<1e-15
assert abs(density_ratio-1.0042857142857142)<1e-14
fig,(ax,bx)=plt.subplots(1,2,figsize=(13,5.8),dpi=120,facecolor='white')
fig.subplots_adjust(left=.065,right=.98,bottom=.23,top=.83,wspace=.29)
x=np.linspace(0,.02,250)
ax.plot(100*x,100*x*(ma/mn-1),color='#24659a',linewidth=2.5)
ax.scatter([1],[100*(density_ratio-1)],color='#ba3b3b',s=65,zorder=4)
ax.annotate('1% argon gives\n0.429% extra density',xy=(1,100*(density_ratio-1)),
xytext=(.12,.66),arrowprops={'arrowstyle':'->','color':'#555'},fontsize=12)
ax.set(xlim=(0,2),ylim=(0,.9),xlabel='Argon mole fraction (%)',
ylabel='Density excess above pure nitrogen (%)',title='Equal pressure and temperature')
ax.grid(alpha=.22)
excess=np.array([0,mixture_mass-reference_mass,colder_mass-reference_mass])*1e6
bx.bar([0,1,2],excess,color=['#9ca9af','#be5b39','#438865'],width=.64)
bx.set_xticks([0,1,2],['Pure nitrogen\n300 K','1% argon mixture\n300 K',f'Pure nitrogen\n{colder:.3f} K'])
bx.tick_params(axis='x',labelsize=11)
bx.set(ylabel='Extra gas mass above reference (mg)',ylim=(0,12),title='Chosen 2.00 L globe at 100 kPa')
for i,value in enumerate(excess):
bx.text(i,value+.35,f'{value:.2f} mg',ha='center',fontsize=12)
bx.grid(axis='y',alpha=.22)
bx.set_axisbelow(True)
bx.text(.5,-.23,f'Reference gas mass: {reference_mass*1000:.5f} g',transform=bx.transAxes,ha='center',fontsize=11)
fig.suptitle('Composition and temperature can give the same weighing signal',fontsize=17,y=.96)
fig.text(.5,.025,'Ideal-gas calculation with stipulated molar masses 28 and 40 g/mol. These are not historical measurements.',
ha='center',fontsize=11)
fig.savefig(Path.cwd()/(Path(__file__).stem+'.png'),facecolor='white')
plt.close(fig)
if __name__=='__main__':
main()