diff --git a/paper/pnas/figs/fig1a.pdf b/paper/pnas/figs/fig1a.pdf index a668b95..5a1b16e 100644 Binary files a/paper/pnas/figs/fig1a.pdf and b/paper/pnas/figs/fig1a.pdf differ diff --git a/paper/pnas/figs/icons/pea.png b/paper/pnas/figs/icons/pea.png deleted file mode 100644 index 5a4f788..0000000 Binary files a/paper/pnas/figs/icons/pea.png and /dev/null differ diff --git a/paper/pnas/figs/icons/pea.svg b/paper/pnas/figs/icons/pea.svg new file mode 100644 index 0000000..d2d65a7 --- /dev/null +++ b/paper/pnas/figs/icons/pea.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/paper/pnas/figs/icons/robot.png b/paper/pnas/figs/icons/robot.png deleted file mode 100644 index d4fe920..0000000 Binary files a/paper/pnas/figs/icons/robot.png and /dev/null differ diff --git a/paper/pnas/figs/icons/robot.svg b/paper/pnas/figs/icons/robot.svg new file mode 100644 index 0000000..1e54892 --- /dev/null +++ b/paper/pnas/figs/icons/robot.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/paper/pnas/main.pdf b/paper/pnas/main.pdf index c96b4f8..5a69f3b 100644 Binary files a/paper/pnas/main.pdf and b/paper/pnas/main.pdf differ diff --git a/paper/pnas/make_figs.py b/paper/pnas/make_figs.py index 65e7a27..1e945db 100644 --- a/paper/pnas/make_figs.py +++ b/paper/pnas/make_figs.py @@ -42,21 +42,41 @@ def save(fig, name): print("wrote", OUT / f"{name}.pdf") +def _icon(svg_name: str): + """Rasterise a committed icon SVG at 2048 px (print-lossless at the ~0.3 in placed size). + + Requires ``rsvg-convert`` (librsvg). The SVGs are the committed source of truth; no derived + PNGs are kept in the repo. + """ + import subprocess + import tempfile + + svg = OUT / "icons" / svg_name + with tempfile.NamedTemporaryFile(suffix=".png") as f: + try: + subprocess.run(["rsvg-convert", "-w", "2048", "-h", "2048", "-o", f.name, str(svg)], + check=True, capture_output=True) + except FileNotFoundError as e: + raise RuntimeError("rsvg-convert (librsvg) is required to rasterise the icon SVGs " + "for fig1a") from e + return plt.imread(f.name) + + # ---------------------------------------------------------------- fig 1: experimental programme def fig1a(): from matplotlib.patches import FancyBboxPatch # (name, architecture, guarantee, edge, cell face, header fill, header text colour, icon) - # Icons: Flaticon #2347052 (green pea, for Mendel) and #10479785 (robot), used under GG's - # paid Flaticon licence. + # Icons: Flaticon #2347052 (green pea, for Mendel) and #10479785 (robot) as committed SVGs, + # used under GG's paid Flaticon licence; rasterised at build time by _icon(). TIERS = [ ("Biological model", "Wright\u2013Fisher simulator (NumPy)", "closed forms \u00b7 bitwise-reproducible", - "#4e8d4e", "#eef6ec", "#c5e0bd", "#2d5b2d", "icons/pea.png"), + "#4e8d4e", "#eef6ec", "#c5e0bd", "#2d5b2d", "pea.svg"), ("Trained networks", "RNN \u00b7 MLP \u00b7 VAE on a synthetic oracle;\nconvolutional VAE on MNIST", "sign-level tests \u00b7 exact oracles", "#5b9bc9", "#eff6fb", "#c9e2f2", "#1f4e79", - "icons/robot.png"), + "robot.svg"), ("Language models", "LoRA specialists on Qwen 0.5B & 7B;\nexact-match verifier", - "seed-replicated signs", "#3c6ea5", "#e7eef8", "#adc8e8", "#1d3f66", "icons/robot.png"), + "seed-replicated signs", "#3c6ea5", "#e7eef8", "#adc8e8", "#1d3f66", "robot.svg"), ] ROWS = [ ("Grounding = immigration", @@ -115,8 +135,8 @@ def fig1a(): linespacing=1.3, color=textcol) ax.text(xc, 0.833, guarantee, ha="center", va="bottom", fontsize=6.4, style="italic", color=textcol, alpha=0.85) - img = plt.imread(str(OUT / icon)) - ax.add_artist(AnnotationBbox(OffsetImage(img, zoom=0.055), + img = _icon(icon) + ax.add_artist(AnnotationBbox(OffsetImage(img, zoom=28.0 / img.shape[0]), (x + cw - gap - 0.024, 0.902), frameon=False)) for i2, (label, definition, cells) in enumerate(ROWS):