diff --git a/paper/pnas/figs/fig1a.pdf b/paper/pnas/figs/fig1a.pdf index 1418ee5..18ff3ed 100644 Binary files a/paper/pnas/figs/fig1a.pdf and b/paper/pnas/figs/fig1a.pdf differ diff --git a/paper/pnas/figs/fig1b.pdf b/paper/pnas/figs/fig1b.pdf index 0791d85..85b4fa4 100644 Binary files a/paper/pnas/figs/fig1b.pdf and b/paper/pnas/figs/fig1b.pdf differ diff --git a/paper/pnas/main.pdf b/paper/pnas/main.pdf index e22cc5f..023c6c6 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 b444064..97d8675 100644 --- a/paper/pnas/make_figs.py +++ b/paper/pnas/make_figs.py @@ -158,25 +158,22 @@ def fig1a(): face = TIERS[j2][4] if cell is None: ax.add_patch(FancyBboxPatch((x + gap, y0), cw - 2 * gap, y1 - y0, - boxstyle="round,pad=0.004", fc="white", ec="#bbbbbb", - lw=0.8, ls=(0, (3, 2)))) + boxstyle="round,pad=0.004", fc="#f3f3f3", ec="none")) ax.text(x + cw / 2, yc, "adds no discriminating test\nat this tier", ha="center", va="center", fontsize=6.4, style="italic", color="#999", linespacing=1.35) elif cell.startswith("LIT:"): ax.add_patch(FancyBboxPatch((x + gap, y0), cw - 2 * gap, y1 - y0, - boxstyle="round,pad=0.004", fc="white", ec="#bbbbbb", - lw=0.8, ls=(0, (3, 2)))) + boxstyle="round,pad=0.004", fc="#f3f3f3", ec="none")) ax.text(x + cw / 2, yc, cell[4:], ha="center", va="center", fontsize=6.4, style="italic", color="#777", linespacing=1.35) elif cell == "OPEN": ax.add_patch(FancyBboxPatch((x + gap, y0), cw - 2 * gap, y1 - y0, - boxstyle="round,pad=0.004", fc="white", ec=edge, - lw=0.8, ls=(0, (3, 2)))) + boxstyle="round,pad=0.004", fc="#f3f3f3", ec="none")) ax.text(x + cw / 2, yc, "open \u2014 the stated gap", ha="center", va="center", fontsize=6.6, style="italic", color=edge) else: ax.add_patch(FancyBboxPatch((x + gap, y0), cw - 2 * gap, y1 - y0, - boxstyle="round,pad=0.004", fc=face, ec=edge, lw=0.9)) + boxstyle="round,pad=0.004", fc=face, ec="none")) ax.text(x + cw / 2, yc + 0.008, cell, ha="center", va="center", fontsize=6.4, linespacing=1.35) if tags[j2]: # where the result lives (the ToC role) @@ -188,23 +185,17 @@ def fig1a(): BLUE, GREEN, GOLD = "#4292c6", "#41ab5d", "#d4a017" -def _robot(ax, x, y, fc="#e8eef5", dots=(), lost=(), w=0.52, h=0.52): - """A friendly robot head with capability dots beneath (gold = the rare skill).""" - from matplotlib.patches import Arc, Circle, FancyBboxPatch +def _robot(ax, x, y, img, dots=(), lost=(), size=0.62): + """The robot icon (the same Flaticon asset as Fig. 1A) with capability dots beneath.""" + from matplotlib.patches import Circle - ax.add_patch(FancyBboxPatch((x - w / 2, y - h / 2), w, h, boxstyle="round,pad=0.03", - fc=fc, ec="#445", lw=1.1)) - for dx in (-w / 4.5, w / 4.5): - ax.add_patch(Circle((x + dx, y + h / 7), w / 9, fc="white", ec="#445", lw=0.7)) - ax.add_patch(Circle((x + dx, y + h / 7), w / 24, fc="#334", ec="none")) - ax.add_patch(Arc((x, y - h / 7), w / 2.4, h / 3.2, theta1=195, theta2=345, ec="#445", lw=1.0)) - ax.plot([x, x], [y + h / 2 + 0.03, y + h / 2 + 0.10], color="#445", lw=1.1) - ax.add_patch(Circle((x, y + h / 2 + 0.135), 0.04, fc="#445", ec="none")) + ax.imshow(img, extent=(x - size / 2, x + size / 2, y - size / 2, y + size / 2), + interpolation="none", zorder=2) marks = [(c, False) for c in dots] + [(c, True) for c in lost] n = len(marks) for i, (c, is_lost) in enumerate(marks): cx = x + (i - (n - 1) / 2) * 0.19 - cy = y - h / 2 - 0.17 + cy = y - size / 2 - 0.13 if is_lost: ax.add_patch(Circle((cx, cy), 0.07, fc="white", ec=c, lw=0.9, ls=(0, (2, 2)))) ax.text(cx, cy - 0.005, "\u00d7", ha="center", va="center", fontsize=6, color=c) @@ -227,6 +218,8 @@ def fig1b(): ax.add_patch(FancyArrowPatch(p, q, arrowstyle=style, mutation_scale=10, color=color, lw=lw, linestyle=ls, shrinkA=shrink, shrinkB=shrink)) + rob = _icon("robot.svg") + # ---------------- left: a society in space (contemporaries exchanging messages) cx, cy, r = 2.45, 2.95, 0.95 dotsets = [(BLUE, GOLD), (GREEN,), (BLUE, GREEN), (GOLD, GREEN), (BLUE,)] @@ -235,7 +228,7 @@ def fig1b(): a = np.pi / 2 + i * 2 * np.pi / 5 x, y = cx + r * np.cos(a) * 1.4, cy + r * np.sin(a) * 0.95 pos.append((x, y)) - _robot(ax, x, y, dots=ds) + _robot(ax, x, y, rob, dots=ds) for i, j2 in [(0, 2), (1, 3), (2, 4), (0, 3), (1, 4)]: arrow(pos[i], pos[j2], color="#99a", lw=0.9, style="<|-|>", shrink=26, ls=(0, (4, 2))) ax.text(pos[0][0] + 0.72, pos[0][1] + 0.38, "hi!", fontsize=8, ha="center", @@ -266,11 +259,11 @@ def fig1b(): p1, p2 = (8.0, 4.05), (9.5, 4.05) c1, c2 = (7.5, 2.80), (9.0, 2.80) g2 = (9.0, 1.60) - _robot(ax, *p1, dots=(BLUE, GOLD)) - _robot(ax, *p2, dots=(GREEN, BLUE)) - _robot(ax, *c1, dots=(BLUE,), lost=(GOLD,)) - _robot(ax, *c2, dots=(BLUE, GREEN, GOLD)) - _robot(ax, *g2, dots=(BLUE, GREEN, GOLD)) + _robot(ax, *p1, rob, dots=(BLUE, GOLD)) + _robot(ax, *p2, rob, dots=(GREEN, BLUE)) + _robot(ax, *c1, rob, dots=(BLUE,), lost=(GOLD,)) + _robot(ax, *c2, rob, dots=(BLUE, GREEN, GOLD)) + _robot(ax, *g2, rob, dots=(BLUE, GREEN, GOLD)) arrow((7.87, 3.51), (7.56, 3.29), color="#666") ax.text(7.42, 3.41, "inherit", ha="right", fontsize=7, style="italic", color="#555") arrow((8.15, 3.49), (8.85, 3.29), color="#666") @@ -296,6 +289,8 @@ def fig1b(): ha="center", fontsize=7.2, style="italic", color="#555") ax.text(8.9, 0.24, "from parent model to child model \u2014 where population genetics applies", ha="center", fontsize=7.2, style="italic", color="#555") + ax.set_xlim(0, W) + ax.set_ylim(0, H) save(fig, "fig1b") # ---------------------------------------------------------------- fig 2: grounding + MNIST