Figuras TikZ en vivo
Una figura en vivo es un dibujo TikZ que el lector puede modificar. El objetivo es el mismo que una figura estática en tikz-dl-visualizer (una idea, hecha obvia), pero ahora el lector hace algo y observa cómo responde la idea: arrastra el punto de inicio y ve cómo el momento cancela el zig-zag, baja la temperatura y ve cómo softmax colapsa a argmax.
Cada figura tiene dos mitades:
| archivo | contiene | compilado por |
|---|---|---|
figure.tex | todo lo que nunca cambia: ejes, contornos, cuadrículas, matrices de valores fijos, etiquetas, la ecuación, y ranuras para el texto en vivo | pdflatex, una vez |
figure.js | todo lo que cambia: parámetros, manejadores, hotspots, un compute(state) puro, y draw(d, state, c) | el navegador, en cada cambio |
scripts/build.py compila el .tex dos veces (una normal, otra con el texto en vivo en colores de ID para recortar esos glifos), exporta el marco de coordenadas TikZ y las cajas de nodos nombrados, ejecuta la especificación bajo node, y escribe:
figure.html: una página autónoma (sin red). Ábrela, inclúyela en un iframe, o publícala.figure.pngmásfigure.<snapshot>.png: el estado predeterminado y cada instantánea, renderizados sin navegador. Así es como ves tu propio trabajo.figure.svg: el estado predeterminado como SVG estático, para artículos y alternativas.
Incluido:
assets/dlviz.sty: la paleta y estilos TikZ (mismo archivo que tikz-dl-visualizer).assets/dllive.sty: lado TeX, las clavesexportylive=y\dlnum.assets/dllive.js: runtime: mapa de coordenadas, API de dibujo, sliders, manejadores, hotspots, reproducción.assets/examples/momentum/: parámetros, un manejador arrastrable, un botón de reproducción, números en vivo, una etiqueta móvil.assets/examples/attention/: celdas exportadas, hotspots al pasar el ratón, un mapa de calor, 29 números en vivo, curvas.references/api.md: la API completa (claves TeX, campos de especificación, llamadas de dibujo). Léelo antes de escribir tu primera especificación en una sesión.references/gotchas.md: problemas que encontramos y sus soluciones. Léelo cuando algo no se vea bien.
Para el lenguaje visual en sí (roles de color, notación, diseño, anotaciones), sigue tikz-dl-visualizer: sus references/visual-language.md y references/archetypes.md se aplican sin cambios. Léelos si no lo has hecho en esta sesión.
Flujo de trabajo
1. Escribe la frase de interacción
Antes de cualquier código, escribe una frase de la forma "el lector hace X y ve Y, lo que muestra Z":
- "Arrastra el punto de inicio y cambia β: el zig-zag a través del valle se cancela mientras el movimiento a lo largo de él se acumula; demasiado β provoca sobreimpulso."
- "Pasa el ratón sobre un token: su fila de A es el conjunto de pesos, y su fila de salida es ese promedio ponderado de las filas de V. Baja τ y los pesos colapsan en una fila."
Si Y sería igual de claro en una figura estática, haz una estática (tikz-dl-visualizer). Usa de uno a tres controles. Cada control debe cambiar algo que el ojo pueda seguir; un slider cuyo efecto no se ve es ruido.
2. Separa lo estático de lo vivo
Dibuja en papel qué cambia. Todo lo demás va en el .tex. Separaciones típicas:
- Estático: ejes, contornos, cuadrículas, bordes de celdas, matrices fijas, etiquetas de tokens, la ecuación, etiquetas de lectura como
\(\beta = {}\), trazos de leyenda. - Vivo: trayectorias, puntos, resaltados, rellenos de mapa de calor, flechas, atenuación y números (como ranuras
\dlnum, para que sigan siendo glifos TeX reales). - Una etiqueta que deba moverse (por ejemplo, una unida a un manejador) también es un nodo
live=, movido cond.label(id, {from, to}).
3. Escribe figure.tex
Comienza desde el ejemplo más cercano. Requerido:
\documentclass[tikz,border=8pt]{standalone}
\usepackage[dark]{dlviz} % [light] para páginas blancas
\usepackage{dllive}
\begin{document}
\begin{tikzpicture}[x=1.15cm, y=1.15cm]
\useasboundingbox (xmin,ymin) rectangle (xmax,ymax); % SIEMPRE: el dibujo en vivo debe caber dentro
...dibujo estático...
\node[cell=coloraqua, export] (A-1-1) at (..) {}; % export: JS puede direccionar esta caja
\node[fit=(Q-1-1)(Q-1-3), inner sep=0, export] (Qrow-1) {}; % caja invisible para un hotspot
\node[anchor=base west, inner sep=0, text=coloraqua] (b) at (..) {\(\beta = {}\)};
\node[live=beta, anchor=base west, inner sep=0, text=coloraqua] at (b.base east) {\dlnum};
\end{tikzpicture}
\end{document}
- Establece la escala con
x=/y=(noscale=), para que 1 unidad en JS sea 1 unidad en TikZ. - Un nodo número en vivo contiene exactamente
\dlnum. Establece su color context=y su tamaño confont=; los comandos de color dentro del nodo lo rompen. - Coloca los números en celdas de tabla con
anchor=mid westen el centro de la celda, luegod.number(id, v, {at: "cell"})los centra. En un\matrixo donde importe la disposición, usa\dlnumin{2em}para que la ranura reserve solo ese ancho. - Si la figura solo tiene sentido con algo seleccionado, ábrela de esa manera:
initial: {hover: "..."}másstickyHover: true. - Nombra las cosas para que JS pueda iterar sobre ellas (
A-\i-\j,Qrow-\i). - Pon un comentario
% Caption:al inicio, como en tikz-dl-visualizer.
4. Escribe figure.js
DLLive.figure({
title: "...", caption: "...cómo interactuar, una o dos frases...",
params: { beta: { label: "β", min: 0, max: 0.99, step: 0.01, value: 0.6 } },
handles: { w0: { value: [-4, 1.5], min: [-5.2, -1.85], max: [5.2, 1.85] } },
hotspots: /^Qrow-\d$/, // nodos exportados que establecen state.hover
play: { param: "t", ms: 110 }, // opcional: anima un parámetro (oculto)
compute: (s) => ({ path: run(s.beta, s.w0) }), // matemáticas puras, memoizadas
draw(d, s, c) { // unidades TikZ, colores dlviz
d.path(c.path, { color: "aqua", width: "thick", dots: true });
d.number("beta", s.beta, { digits: 2 });
},
snapshots: [{ name: "overshoot", beta: 0.95 }], // PNGs adicionales para verificar
tests: [{ name: "matches numpy", state: { beta: 0.4 }, check: (c) => Math.abs(c.path[30][0] - 1.036e-5) < 1e-8 || `got ${c.path[30]}` }],
});
- Las matemáticas viven en
compute, y deben ser correctas. Escribe primero una referencia en Python (numpy), luego añade una entradatestsque compare el JS contra un número que calculaste en Python. Nunca confíes en matemáticas escritas solo en tu cabeza. drawsolo dibuja: sin cambios de estado, sin aleatoriedad (usa un RNG con semilla encomputesi necesitas ruido), y se ejecuta en cada fotograma.- Usa roles de color dlviz (
aqua,red,orange!55!bg...) y grosores TikZ (thin,thick,very thick), para que la superposición se vea como el andamio. - Añade una instantánea para cada estado que importe: un extremo de cada slider, un hover, mitad de animación. Ahí es donde se esconden las superposiciones.
5. Construye
uv run --with pymupdf python <skill-dir>/scripts/build.py ruta/a/figure.tex
Imprime los nombres de nodos exportados y ranuras en vivo, cuántos nodos coincidieron con los hotspots, PASS/FAIL para cada test, y WARN por dibujo fuera de la página o texto TeX cortado en su borde. Los errores nombran la ranura, nodo o parámetro problemático. Después de un cambio solo en el .js, añade --no-tex (aproximadamente 1 segundo).
6. Mira, critica, itera
Abre cada PNG que escribió (herramienta Read) y verifica, como para una figura estática:
- ¿La parte en vivo se alinea con el andamio (las trayectorias comienzan en el punto correcto, los números se asientan en sus celdas, los resaltados abrazan sus filas)?
- En cada instantánea, ¿hay superposiciones: una trayectoria a través de una lectura, una curva sobre números, texto fuera de su celda, algo recortado en el borde?
- ¿Los extremos de los controles aún se leen bien (β = 0.99, τ = 0.2, un manejador en una esquina)?
- ¿Puede el ojo encontrar la idea en tres segundos en el estado predeterminado? El estado predeterminado es lo que ve una miniatura y un lector que hojea.
- Los colores mantienen sus roles tanto en el andamio como en la superposición.
Corrige y reconstruye. Dos o tres rondas es normal.
Luego prueba la página real si tienes un navegador (el panel Navegador incorporado): normalmente rechaza file://, así que sirve la carpeta, por ejemplo con una entrada .claude/launch.json {"name": "fig", "runtimeExecutable": "python3", "runtimeArgs": ["-m", "http.server", "8800", "--directory", "<carpeta>"], "port": 8800} y preview_start. Arrastra, desliza, pasa el ratón y reproduce; en la consola, DLLive.state() muestra el estado actual. Las instantáneas no muestran guiones ni cursores de hover.
7. Entrega
Dale al usuario el PNG (estado predeterminado), la ruta a figure.html, y una breve guía de lectura: qué probar primero y qué observar ("Arrastra w₀ hacia la dirección empinada, luego sube β..."). Si quieren un enlace compartible, publica el HTML como un Artefacto; es autónomo, por lo que no se necesitan archivos adicionales. Menciona el siguiente control o figura natural en una línea.
Inserción
- Varias figuras en una página, o una página con su propio tema claro/oscuro (tikz-explorer-book hace esto a través de su
tools/fig.sh): construir con--themes dark,light --embed. Eso compila el andamio en ambos temas y escribefigure.live.html, un fragmento (<div class="dl-live">más un<script>DLLive.load("name", ...)</script>). La página anfitriona incluyeassets/dllive.jsuna vez antes de los fragmentos, y las reglas CSS marcadas como "figura en vivo" enassets/template.html. Muestra el andamio para el tema actual con--show-d/--show-l. El runtime sigue el tema de la página (data-theme="dark|light"en<html>, o la configuración del sistema) y recolorea la superposición. También se escribe-light.png. - Autónoma o un Artefacto:
figure.htmltal cual. Con--themes dark,lightsigue el tema del espectador; de lo contrario mantiene el tema del.tex. - Diapositivas: usa
figure.png/figure.svgpara la diapositiva estática, y enlaza el HTML. - Artículo: usa
figure.svgo el PDF del andamio en.dllive/; el estado predeterminado estático es una figura completa por sí sola. Para figuras solo impresas, tikz-dl-visualizer es la herramienta más adecuada.