$npx -y skills add neuromechanist/research-skills --skill svg-figureThis skill should be used when the user asks to "create an SVG figure", "make a schematic", "draw a diagram", "create a schematic diagram", "draw a flowchart", "draw a process flow", "draw a workflow", "draw a workflow diagram", "make an SVG schematic", "create a process diagram"
| 1 | # SVG Figure |
| 2 | |
| 3 | Conventions for SVG schematics and diagrams (flowcharts, process diagrams, system diagrams, anatomical illustrations) with element-consistency guarantees: text aligned to box bounds, arrows pointing at their targets, lines passing under shapes by z-order. The output SVGs are designed to be composed as panels by the `[[scientific-figure]]` skill and verified by the `[[figure-qa]]` agent's SVG branch. |
| 4 | |
| 5 | ## When to use this skill |
| 6 | |
| 7 | **For new programmatic work, use `[[svg-primitives]]` instead.** It implements every convention below as a mechanical guarantee — text auto-fits boxes, arrowheads stay tangent-correct on curves, paint order is deterministic, and `Canvas.save(validate='strict')` raises if any of those invariants are violated. `examples/schematic_from_primitives.py` in this skill is the canonical programmatic example. |
| 8 | |
| 9 | Reach for **this** skill when: |
| 10 | |
| 11 | - You are writing SVG **by hand** or with an editor like Inkscape, and need the conventions the figure-qa agent expects. |
| 12 | - You are using a non-Python tool to emit SVG and want to know what shape it should take. |
| 13 | - You are reading hand-authored SVG produced by an external collaborator and want to understand the layout grammar. |
| 14 | - You are debugging a figure-qa finding on an SVG that did not come from `svg-primitives`. |
| 15 | - The figure is a **schematic** (boxes, arrows, labels) rather than data plotted from numbers — for plots use `[[plot-styling]]`. |
| 16 | |
| 17 | Reach for a different tool when: |
| 18 | |
| 19 | - You are writing Python → use `[[svg-primitives]]`. |
| 20 | - The figure is a **plot** of data → use `[[plot-styling]]`. |
| 21 | - The figure is **pictorial substrate** (a brain, a microscope, a setup photo aesthetic) → use `[[ai-full-figure]]` for the substrate and overlay labels via `[[svg-primitives]]`. |
| 22 | - The figure needs **icon-style elements** repeated across panels → generate the icons via `[[transparent-icons]]` and place them as `<image>` references in the SVG. |
| 23 | |
| 24 | ## Programmatic authoring (recommended path) |
| 25 | |
| 26 | See `[[svg-primitives]]`. The canonical example in this skill is `examples/schematic_from_primitives.py` which reproduces `examples/schematic.svg` using `Canvas`, `LabeledBox`, `Arrow.connect`, and `Annotation`. Run it: |
| 27 | |
| 28 | ```bash |
| 29 | cd plugins/figures/skills |
| 30 | uv run --with drawsvg --with svgpathtools --with Pillow --with fonttools \ |
| 31 | --with cairosvg --with lxml \ |
| 32 | python svg-figure/examples/schematic_from_primitives.py |
| 33 | ``` |
| 34 | |
| 35 | ## Hand-authoring conventions |
| 36 | |
| 37 | The recipes below apply when SVG is written by hand or emitted by a non-Python tool. `[[svg-primitives]]` enforces every one of them mechanically; this section is the reference for the underlying SVG conventions and is what the figure-qa agent expects when validating arbitrary SVG inputs. |
| 38 | |
| 39 | ### 1. Sizing |
| 40 | |
| 41 | Set explicit `width`/`height` and a matching `viewBox` so user units equal mm (the same convention `[[scientific-figure]]` uses for composition): |
| 42 | |
| 43 | ```svg |
| 44 | <svg xmlns="http://www.w3.org/2000/svg" |
| 45 | width="89mm" height="60mm" viewBox="0 0 89 60"> |
| 46 | ... |
| 47 | </svg> |
| 48 | ``` |
| 49 | |
| 50 | Now every coordinate inside the SVG is in mm, **including font-size** (it is a length in user units, not points). A `<rect width="20" height="10">` is 20mm × 10mm, and a `<text font-size="9">` is 9 mm tall (~25 pt). To target a physical point size, convert: `N pt = N × 25.4/72 mm`, so 6 pt is `font-size="2.1"` and Nature's 5 pt minimum is `font-size="1.76"`. `figure-qa` reports the physical point size, so keep body labels at `font-size` ≥ ~1.8. |
| 51 | |
| 52 | > *Done automatically by `[[svg-primitives]]`*: `Canvas(width_mm, height_mm)` sets the viewBox and units. |
| 53 | |
| 54 | ### 2. Text aligned to box bounds |
| 55 | |
| 56 | When labelling a box, the label belongs **inside** the box's bounding rectangle. Use `text-anchor="middle"` plus `dominant-baseline="middle"` and center the text at the box's centroid: |
| 57 | |
| 58 | ```svg |
| 59 | <rect x="10" y="10" width="30" height="14" fill="#F4F1DE" stroke="#1F3A5F" stroke-width="0.8" rx="1.5"/> |
| 60 | <text x="25" y="17" text-anchor="middle" dominant-baseline="middle" |
| 61 | font-family="Helvetica, Arial, sans-serif" font-size="2.1">Cortex</text> |
| 62 | ``` |
| 63 | |
| 64 | The text x is the rect's `x + width/2 = 25`. The text y is `y + height/2 = 17`. For tighter visual alignment with the rounded `rx` corner, nudge the y by ~0.5–1 mm; ver |