Deployment Scenarios¶
The phase plane widget supports three deployment modes, each optimized for a different use case.
1. Jupyter Notebook / JupyterLab¶
The native environment. All interactivity is client-side after the initial cell execution.
from phase_plane_widget import PhasePlaneWidget
widget = PhasePlaneWidget(model_name="mpr")
widget.params["J"] = 20.0
widget
How It Works¶
- Python creates the widget and syncs initial state via
traitlets anywidgetloads the JS front-end in the notebook- All subsequent interaction (sliders, clicks, sweeps) is handled by JavaScript — no Python kernel round-trips
- Python can still read back computed data (nullclines, fixed points, trajectories) via the synced traitlets
Exporting Notebooks¶
Use jupytext to keep notebooks in plain .py percent-format:
jupytext --to notebook demo.py -o demo.ipynb
jupytext --sync demo.ipynb # keep .py and .ipynb in sync
2. VS Code (Jupyter Extension)¶
VS Code's built-in Jupyter extension supports anywidget out of the box.
from phase_plane_widget import PhasePlaneWidget
widget = PhasePlaneWidget()
widget # Renders in the VS Code output panel
No extra configuration needed — the same anywidget bridge works transparently.
3. Standalone HTML (No Kernel)¶
For blogs, documentation, course materials, or any static site where you cannot run a Python kernel:
widget = PhasePlaneWidget(model_name="mpr")
widget.params["delta"] = 1.0
widget.params["eta_bar"] = -5.0
widget.params["J"] = 15.0
widget.to_standalone_html("mpr_demo.html", title="MPR Phase Plane")
What You Get¶
A single self-contained .html file (~40–50 KB) containing:
- All three model definitions (Wilson-Cowan, FHN, MPR)
- RK4 ODE solver
- Newton-Raphson fixed-point finder
- Nullcline and vector field computation
- HTML5 Canvas rendering engine
- Parameter sweep engine
No external dependencies. No CDN. No Python runtime. Works offline.
Embedding in MkDocs / GitHub Pages¶
The generated HTML can be embedded in an <iframe>:
<iframe src="demos/mpr_bistable.html"
width="100%" height="750"
frameborder="0"
style="border:1px solid #ddd; border-radius:8px;">
</iframe>
This entire documentation site uses this technique — every demo is a live, interactive widget running in your browser.
4. ipywidgets embed_minimal_html¶
For a traditional ipywidgets-based export (requires a web server with widget support):
from ipywidgets.embed import embed_minimal_html
from phase_plane_widget import PhasePlaneWidget
widget = PhasePlaneWidget()
embed_minimal_html("export.html", views=[widget], title="Phase Plane",
drop_defaults=False)
Requires widget JS runtime
embed_minimal_html produces a file that references the anywidget CDN bundle via RequireJS. This does not work when opened as a local file (file://) because RequireJS cannot load ES modules. Use to_standalone_html() instead for true offline/self-contained deployment.
Comparison¶
| Scenario | Python Kernel | Internet | File Size | Best For |
|---|---|---|---|---|
| Jupyter Notebook | Required at runtime | Optional | ~40KB JS | Research, exploration |
| VS Code | Required at runtime | Optional | ~40KB JS | IDE-based workflow |
| Standalone HTML | None | None | ~45KB | Docs, blogs, courses |
embed_minimal_html |
Required to generate | Required to view | ~2KB + CDN | Sharing with Jupyter users |
CI/CD: Auto-Generated Documentation¶
This site is built automatically by a GitHub Actions workflow that:
- Installs the package
- Generates standalone HTML demos for each model
- Builds mkdocs with mkdocstrings API docs
- Deploys to GitHub Pages
The demos are live widgets — you can interact with them directly in the documentation.