Skip to content

Commit e8fff92

Browse files
committed
feat: SVG and TikZ export for phase plane figures
- Embed canvas2svg library in widget.js for SVG export from HTML5 Canvas - Add export buttons (SVG, TikZ) to widget UI with CSS styling - Implement exportToSVG() that replays phase plane drawing through C2S mock context - Add export_tikz() to PhasePlaneWidget for PGFPlots code generation - Generate self-contained standalone .tex with embedded data tables - Vector field as \draw[-stealth] arrows, nullclines as \addplot, trajectories as smooth curves, fixed points as TikZ nodes with shape/colour encoding - Parameter annotation with underscore escaping for LaTeX safety - Full test suite: 139 passed, 5 skipped, pdflatex compilation verified - Document both export methods in deployment.md
1 parent 35f1261 commit e8fff92

5 files changed

Lines changed: 1585 additions & 22 deletions

File tree

docs/deployment.md

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -202,6 +202,34 @@ The widget automatically locates fixed points (equilibria) by intersecting nullc
202202

203203
The color key (green for stable, red/orange for unstable, purple for saddle) is preserved alongside the new shapes so that colour-blind users can still distinguish categories.
204204

205+
### TikZ / PGFPlots Export
206+
207+
For publication-quality figures, the widget can export the current phase plane to a self-contained ``.tex`` file:
208+
209+
```python
210+
from tvb_phaseplane import PhasePlaneWidget
211+
212+
widget = PhasePlaneWidget(model_name="wilson_cowan")
213+
# ... interact with the widget ...
214+
widget.export_tikz("phase_plane.tex")
215+
```
216+
217+
The generated ``.tex`` file embeds all data (vector field arrows, nullclines, trajectory, fixed points) as inline ``coordinates`` and ``\draw`` commands. It requires the ``pgfplots`` package and compiles with ``pdflatex`` or ``lualatex``:
218+
219+
```bash
220+
pdflatex phase_plane.tex
221+
```
222+
223+
### What Is Exported
224+
225+
- **Vector field**: a grid of ``\draw[-stealth, gray]`` arrows computed and normalized in Python.
226+
- **Nullclines**: ``\addplot[blue, ...]`` and ``\addplot[red, ...]`` with embedded coordinate lists.
227+
- **Trajectory**: ``\addplot[green!60!black, ...]`` with embedded coordinate list.
228+
- **Fixed points**: TikZ ``\node`` markers whose shapes encode stability (circle for nodes/foci, diamond for saddles; green for stable, red for unstable, purple for saddles).
229+
- **Parameter annotation**: a small ``\node`` in the top-left corner listing the current model name and parameter values.
230+
231+
The widget UI also contains an **Export TikZ** button (beside the Export SVG button) that sends a message to the Python kernel for potential future integration.
232+
205233
### References
206234

207235
- Scholarpedia, *Equilibrium*: http://www.scholarpedia.org/article/Equilibrium — in particular the two-dimensional analysis and Figure 3 showing the eigenvalue-based classification diagram.

src/tvb_phaseplane/static/widget.css

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -579,3 +579,27 @@
579579
aspect-ratio: 1 / 1;
580580
max-height: none;
581581
}
582+
583+
.ppw-export-row {
584+
margin-top: 8px;
585+
display: flex;
586+
gap: 8px;
587+
}
588+
.ppw-export-row button {
589+
flex: 1;
590+
padding: 6px 10px;
591+
font-size: 12px;
592+
font-weight: 600;
593+
border: 1px solid #ced4da;
594+
border-radius: 4px;
595+
background: #fff;
596+
color: #495057;
597+
cursor: pointer;
598+
}
599+
.ppw-export-row button:hover {
600+
background: #e9ecef;
601+
}
602+
.ppw-export-row button:disabled {
603+
opacity: 0.5;
604+
cursor: not-allowed;
605+
}

0 commit comments

Comments
 (0)