codexreplica-plating-velveteen-spatial-transfer.py
replica-plating-velveteen-spatial-transfer.py
"""Original replica-plating schematic. Run from _media; Python 3.14, matplotlib 3.10.7."""
from pathlib import Path
import matplotlib.pyplot as plt
from matplotlib.patches import Circle, Ellipse, FancyArrowPatch, Polygon, Rectangle
BLUE = "#236c91"
ORANGE = "#bb6615"
GRAY = "#59636b"
SITES = [(-0.43, 0.35), (0.05, 0.52), (0.44, 0.22), (-0.50, -0.14),
(0.02, -0.03), (0.37, -0.39), (-0.25, -0.49)]
def arrow(ax, start, end, color=GRAY, dashed=False, curve=0):
ax.add_patch(FancyArrowPatch(start, end, arrowstyle="-|>", mutation_scale=14,
color=color, lw=1.7, linestyle="--" if dashed else "-",
connectionstyle=f"arc3,rad={curve}"))
def plate(ax, center, label, surviving=None, fabric=False):
x, y = center
ax.add_patch(Circle(center, 0.80, fc="#f5f8fa", ec=GRAY, lw=1.5,
hatch="..." if fabric else None))
ax.add_patch(Polygon([(x - .08, y + .88), (x + .08, y + .88),
(x, y + .73)], color=GRAY))
for i, (dx, dy) in enumerate(SITES):
if surviving is None or i in surviving:
ax.add_patch(Circle((x + dx, y + dy), .067, fc=BLUE, ec="white", lw=.6))
ax.text(x, y - 1.03, label, ha="center", va="top", fontsize=11, zorder=5,
bbox={"fc": "white", "ec": "none", "pad": 1})
def main():
plt.rcParams.update({"font.family": "DejaVu Sans", "font.size": 11})
fig = plt.figure(figsize=(11, 6.6), dpi=110, facecolor="white")
ax = fig.add_axes([.03, .05, .94, .85])
ax.set(xlim=(0, 11), ylim=(-.7, 6), aspect="equal")
ax.axis("off")
fig.suptitle("Replica plating preserves a spatial address", y=.97, fontsize=18)
ax.text(.10, 5.65, "Carrier: separated side view", fontsize=13, weight="bold")
ax.text(4.05, 5.65, "Sample transfer: aligned plate views", fontsize=13, weight="bold")
ax.plot([3.65, 3.65], [.1, 5.8], color="#dde2e5")
# The master is inverted, with its culture surface facing the fabric.
ax.add_patch(Rectangle((.65, 4.65), 2.3, .18, fc="#edf3f5", ec=GRAY))
ax.add_patch(Rectangle((.67, 4.63), 2.26, .04, fc="#ded5b5", ec="none"))
for x in [.9, 1.5, 2.4]:
ax.add_patch(Ellipse((x, 4.61), .17, .055, fc=BLUE))
ax.text(1.80, 5.08, "Inverted master plate", ha="center")
arrow(ax, (1.80, 4.47), (1.80, 4.01))
ax.text(2.05, 4.24, "light contact", fontsize=10)
ax.add_patch(Rectangle((.70, 2.02), 2.2, 1.82, fc="#e4d6c1", ec=GRAY))
ax.add_patch(Ellipse((1.80, 2.02), 2.2, .28, fc="#e4d6c1", ec=GRAY))
ax.add_patch(Ellipse((1.80, 3.84), 2.2, .28, fc="#e8e0ec", ec=GRAY))
for x in [0.86 + .095 * i for i in range(21)]:
ax.plot([x, x], [3.83, 3.99], color="#8d729b", lw=1)
ax.add_patch(Rectangle((.65, 3.59), 2.3, .14, fc="#a0aab0", ec=GRAY))
ax.text(1.80, 3.27, "Wood or cork\nsupport", ha="center", va="center")
ax.annotate("Sterile velveteen\npile faces upward", xy=(1.0, 3.96), xytext=(.05, 1.18),
arrowprops={"arrowstyle": "-", "color": GRAY}, fontsize=10)
ax.annotate("Retaining hoop", xy=(2.76, 3.67), xytext=(2.1, .60),
arrowprops={"arrowstyle": "-", "color": GRAY}, fontsize=10, ha="center")
plate(ax, (5.05, 4.2), "Master\nsource retained")
plate(ax, (7.55, 4.2), "Fabric imprint\nsamples at matching sites", fabric=True)
plate(ax, (6.00, 1.20), "Growth-supporting\ncontrol replica")
plate(ax, (9.45, 1.20), "Challenged replica\ntwo growing sites", surviving={1, 5})
arrow(ax, (5.95, 4.20), (6.65, 4.20))
arrow(ax, (7.20, 3.30), (6.28, 2.18))
arrow(ax, (8.00, 3.30), (9.10, 2.18))
ax.text(9.35, 4.05, "▲ same orientation\n on every plate", ha="center", fontsize=10)
arrow(ax, (10.33, 1.40), (5.55, 5.03), color=ORANGE, dashed=True, curve=.35)
ax.text(8.40, 5.18, "Read location → recover from master", color=ORANGE,
ha="center", fontsize=10, bbox={"fc": "white", "ec": "none", "pad": 2})
ax.text(7.65, -.58, "Original schematic • invented positions • no measured growth data",
fontsize=9, color=GRAY, ha="center")
fig.savefig(Path.cwd() / f"{Path(__file__).stem}.png", facecolor="white")
plt.close(fig)
if __name__ == "__main__":
main()