codexosmosis-concentration-pressure-cases.py
osmosis-concentration-pressure-cases.py
"""Plot an explicitly stipulated dilute ideal osmotic balance (Python 3.14)."""
from pathlib import Path
import matplotlib.pyplot as plt
import numpy as np
R = 8.31446261815324
T = 300.0
C_A = 10.0 # mol/m^3; neutral retained solute
C_B = 30.0
BALANCE_KPA = R * T * (C_B - C_A) / 1000
def main():
fig, ax = plt.subplots(figsize=(10.5, 6.3), facecolor="white")
dp = np.linspace(-5, 90, 300)
drive = BALANCE_KPA - dp
ax.fill_between(dp, 0, drive, where=drive >= 0, color="#dceef5")
ax.fill_between(dp, 0, drive, where=drive <= 0, color="#efe4f4")
ax.plot(dp, drive, color="#285e76", lw=2.8)
ax.axhline(0, color="#68747a", lw=1)
cases = [
(0, "No pressure difference\nNet water: A → B", (15, 34), "#147493"),
(BALANCE_KPA, "Balance: 49.89 kPa\nZero net water transfer", (42, 22), "#546556"),
(75, "Excess pressure: 75 kPa\nNet water: B → A", (63, -42), "#735094"),
]
for pressure, label, xytext, color in cases:
y = BALANCE_KPA - pressure
ax.scatter([pressure], [y], s=70, color=color, zorder=5)
ax.annotate(label, (pressure, y), xytext, fontsize=11, color=color,
ha="center", va="center", arrowprops={"arrowstyle": "->", "color": color},
bbox={"boxstyle": "round,pad=0.4", "fc": "white", "ec": color})
ax.set(xlim=(-5, 90), ylim=(-53, 60),
xlabel=r"Solution-side excess pressure $\Delta P=P_B-P_A$ (kPa)",
ylabel=r"Water-potential difference $\Psi_A-\Psi_B$ (kPa)")
ax.set_title(r"$\Psi_A-\Psi_B=RT(c_B-c_A)-\Delta P$", fontsize=16, pad=16)
ax.grid(alpha=0.15)
fig.suptitle("Stipulated concentration–pressure cases", fontsize=17, y=0.97)
fig.text(0.5, 0.865, r"$T=300\,\mathrm{K}$; $c_A=10$, $c_B=30\,\mathrm{mol\,m^{-3}}$ (10 and 30 mmol/L)", ha="center", fontsize=12)
fig.text(0.5, 0.06, "Water passes; neutral solute is retained. Dilute ideal solutions; pressures at the same height.", ha="center", fontsize=10)
fig.text(0.5, 0.026, "Instantaneous reservoir conditions, not measurements or a time course. Permeability sets the rate.", ha="center", fontsize=10)
fig.subplots_adjust(left=0.12, right=0.97, top=0.78, bottom=0.17)
fig.savefig(Path(__file__).stem + ".png", dpi=100, facecolor="white", transparent=False)
plt.close(fig)
if __name__ == "__main__":
main()