"""Original dialysis schematic; run from _media (Python 3.14, matplotlib 3.10).""" from pathlib import Path import matplotlib.pyplot as plt from matplotlib.patches import Circle, FancyArrowPatch, FancyBboxPatch, Rectangle def ion(ax, x, y, sign): color = "#137caf" if sign == "+" else "#c45b19" ax.add_patch(Circle((x, y), 0.105, facecolor=color, edgecolor="white", lw=0.7)) ax.text(x, y, sign, ha="center", va="center", color="white", fontsize=11, weight="bold") def protein(ax, x, y, radius=0.29): ax.add_patch(Circle((x, y), radius, facecolor="#7852a5", edgecolor="#4f3275", lw=1.2)) ax.text(x, y, "P", ha="center", va="center", color="white", fontsize=15, weight="bold") def arrow(ax, start, end, color="#334c62", style="->", lw=1.7): ax.add_patch(FancyArrowPatch(start, end, arrowstyle=style, mutation_scale=13, lw=lw, color=color)) def main(): fig, ax = plt.subplots(figsize=(10.4, 5.7), dpi=120, facecolor="white") ax.set(xlim=(0, 12), ylim=(0, 6.5)) ax.set_axis_off() ax.text(6, 6.18, "Dialysis: change the solution around a retained protein", ha="center", fontsize=17, weight="bold") ax.add_patch(Rectangle((0.45, 1.4), 4.8, 3.9, facecolor="#eaf5fa", edgecolor="#59758a", lw=1.4)) ax.text(2.85, 5.0, "External bath (dialysate)", ha="center", fontsize=12) bag = FancyBboxPatch((1.35, 2.02), 2.0, 2.27, boxstyle="round,pad=0.05,rounding_size=0.28", facecolor="white", edgecolor="#52656e", lw=3) ax.add_patch(bag) ax.text(2.35, 3.95, "Sample", ha="center", fontsize=12) protein(ax, 1.86, 3.08) protein(ax, 2.7, 2.7) for x, y, sign in [(2.55, 3.48, "+"), (2.95, 3.1, "−"), (1.7, 2.47, "+"), (2.2, 2.65, "−"), (2.97, 3.62, "+"), (2.17, 3.54, "−"), (4.3, 3.6, "+"), (4.45, 2.35, "−")]: ion(ax, x, y, sign) arrow(ax, (3.48, 3.15), (4.1, 3.15)) ax.text(4.22, 2.95, "Net salt\nmovement", fontsize=10, ha="center", va="top") ax.text(2.85, 1.73, "Bag wall = semipermeable membrane", ha="center", fontsize=10) ax.text(2.85, 0.83, "Fresh bath removes escaped salt\nand renews the concentration difference", ha="center", fontsize=11) arrow(ax, (3.4, 4.15), (6.08, 5.35), color="#8a979f", lw=1.1) arrow(ax, (3.4, 2.18), (6.08, 1.75), color="#8a979f", lw=1.1) ax.text(6.9, 5.65, "Enlarged wall", ha="center", fontsize=12, weight="bold") ax.text(5.85, 4.77, "Sample side", ha="center", fontsize=11) ax.text(8.02, 5.08, "Bath side", ha="left", fontsize=11) # Openings represent passage schematically, not measured pore geometry. for low, high in [(1.7, 2.78), (3.2, 3.9), (4.32, 4.92)]: ax.add_patch(Rectangle((6.5, low), 0.75, high - low, facecolor="#cbd4d9", edgecolor="#52656e", lw=1)) ion(ax, 5.9, 4.1, "+") ion(ax, 7.82, 2.97, "−") arrow(ax, (6.08, 4.1), (7.72, 4.1), color="#137caf") arrow(ax, (7.62, 2.99), (5.96, 2.99), color="#c45b19") protein(ax, 5.85, 2.12, radius=0.34) arrow(ax, (6.23, 2.12), (6.43, 2.12), color="#7852a5") ax.plot([6.45, 6.45], [1.94, 2.30], color="#7852a5", lw=2.5) ax.text(8.12, 4.09, "Small salt ions cross\nin both directions", fontsize=12, va="center") ax.text(8.12, 2.22, "Large protein\nis retained", fontsize=12, va="center", color="#624089") ax.text(8.3, 0.8, "Schematic only: symbols and gaps are not to scale.\nMWCO is a retention rating, not a sharp pore diameter.", ha="center", fontsize=10, color="#46535d") fig.subplots_adjust(left=0.015, right=0.99, bottom=0.015, top=0.99) fig.savefig(Path(__file__).with_suffix(".png").name, facecolor="white", transparent=False) plt.close(fig) if __name__ == "__main__": main()