Van der Waals equation P-V-T surface for CO₂
Physical Chemistry
Example from the compendium of canonical charts
Python Code
"""Physical Chemistry — Van der Waals equation P-V-T surface for CO₂."""
import numpy as np
import plotly.graph_objects as go
# Van der Waals constants for CO₂
# P = RT/(V-b) - a/V²
A_CO2 = 3.658 # L²·atm/mol²
B_CO2 = 0.04286 # L/mol
R_GAS = 0.08206 # L·atm/(mol·K)
# Critical point: Tc = 8a/(27Rb), Vc = 3b, Pc = a/(27b²)
T_c = 8 * A_CO2 / (27 * R_GAS * B_CO2) # ≈ 304 K
V_c = 3 * B_CO2 # ≈ 0.129 L/mol
P_c = A_CO2 / (27 * B_CO2**2) # ≈ 72.8 atm
def generate():
print(f"computing CO₂ Van der Waals P-V-T surface (Tc={T_c:.1f}K, Vc={V_c:.3f}L, Pc={P_c:.1f}atm) …")
# Grid: V from just above b to 3 L/mol, T from 250 K to 420 K
V = np.linspace(B_CO2 + 0.01, 3.0, 80)
T = np.linspace(250, 420, 60)
VV, TT = np.meshgrid(V, T)
PP = R_GAS * TT / (VV - B_CO2) - A_CO2 / VV**2
# Clip to physical pressure range and mask unphysical region
PP = np.clip(PP, -5, 120)
# Isothermal colorscale — color by temperature
colorscale = [
[0.0, "#52B3D0"], # low T: teal
[0.35, "#845EEE"], # mid-low: violet
[0.65, "#E9A23B"], # mid-high: orange
[1.0, "#DA5597"], # high T: pink
]
fig = go.Figure(data=go.Surface(
x=V,
y=T,
z=PP,
surfacecolor=TT,
colorscale=colorscale,
colorbar=dict(title="T (K)", len=0.6),
hovertemplate="V=%{x:.3f} L/mol<br>T=%{y:.0f} K<br>P=%{z:.1f} atm<extra></extra>",
cmin=250,
cmax=420,
))
# Critical point marker
fig.add_trace(go.Scatter3d(
x=[V_c], y=[T_c], z=[P_c],
mode="markers",
marker=dict(color="white", size=6, symbol="circle",
line=dict(color="#333", width=1)),
name=f"Critical point ({T_c:.0f} K, {P_c:.1f} atm)",
hovertemplate=f"Critical point<br>Tc={T_c:.0f} K, Vc={V_c:.3f} L/mol, Pc={P_c:.1f} atm<extra></extra>",
))
fig.update_layout(
scene=dict(
xaxis_title="Molar Volume (L/mol)",
yaxis_title="Temperature (K)",
zaxis_title="Pressure (atm)",
camera=dict(eye=dict(x=1.8, y=-1.8, z=0.8)),
),
legend=dict(x=0.0, y=1.0),
margin=dict(t=20, b=20, l=20, r=20),
height=620,
)
return fig
if __name__ == "__main__":
generate()
Made with Plotly