bifurcation
analysis.bifurcation
Bifurcation analysis result objects and helpers.
Contains the BifurcationResult class whose instances are returned by model.run(format="bifurcation-julia", ...).
Key attributes
df : pandas.DataFrame Continuation branch points with columns (x, param, itnewton, itlinear, ds, n_unstable, n_imag, stable, step, specialpoint, …). hopf_indices / bp_indices : list[int] Row indices in df where Hopf / Branch (bp) special points occur. hopf_steps / bp_steps : list[int] Corresponding continuation step values. periodic_orbits : list[BifurcationResult | Any] If periodic orbits were computed in Julia (po_results), each periodic orbit branch is wrapped as a child BifurcationResult when possible; otherwise the raw Julia object is stored.
Attributes
| Name | Description |
|---|---|
| BIF_STYLES | |
| PO_REDUCTIONS |
Classes
| Name | Description |
|---|---|
| BifurcationResult | Backend-agnostic bifurcation result. |
| CurvePicker | Click any branch line to inspect the underlying point. |
BifurcationResult
analysis.bifurcation.BifurcationResult(br=None, *, df=None, **kwargs)Backend-agnostic bifurcation result.
A single BifurcationResult represents one continuation branch (equilibrium, periodic orbit, or codim-2 curve) regardless of the backend that produced it (BifurcationKit.jl, PyRates/PyCoBi, AUTO-07p/numcont). Once the data lives in self.df and the nested periodic_orbits / codim2_curves lists, all plotting, legend, and export methods (plot, plot_3d, bif_legend, enable_picker, …) work uniformly across backends.
There are no backend-specific result subclasses. Each adapter extracts a unified DataFrame and either calls the constructor directly with df=... or one of the factory shortcuts:
BifurcationResult.from_bifkit(br, ...)— BifurcationKit.jlContResult(juliacall).BifurcationResult.from_pycobi(ode, cont_name, ...)— PyRates / PyCoBiODESystemcontinuations.BifurcationResult.from_auto(bd, ...)— in-tree AUTO-07pbifDiag(numcont backend).
All visual differences between backends are encoded in the unified :data:BIF_STYLES registry, not in subclasses.
Methods
| Name | Description |
|---|---|
| animate | Animate dynamics alongside this 3D bifurcation diagram. |
| bif_legend | Add a curated legend listing the selected TYs. |
| extract_orbit_meshes | Extract full periodic orbit solution meshes from a PO branch. |
| from_auto | Wrap an AUTO-07p bifDiag (numcont backend). |
| from_bifkit | Wrap a BifurcationKit.jl ContResult (juliacall object). |
| from_pycobi | Wrap a PyRates / PyCoBi continuation by name. |
| plot_3d | Plot 3D bifurcation diagram with periodic orbit surfaces. |
| plot_special_points | Mark codim-1 special points (LP/HB/BP/PD/TR/…) on ax. |
animate
analysis.bifurcation.BifurcationResult.animate(
dynamics,
parameter,
values,
*dims,
kind='phaseplane',
VOI=None,
interval=80,
figsize=(11, 4.8),
title_fmt='{name} = {value:+.2f}',
marker_kwargs=None,
simulation=False,
simulation_duration=200.0,
simulation_dt=0.01,
simulation_backend='tvboptim',
simulation_initial_values=None,
trajectory_kwargs=None,
show_periodic_orbit=True,
orbit_kwargs=None,
**plot_kwargs,
)Animate dynamics alongside this 3D bifurcation diagram.
For each value of parameter a left panel re-renders a Dynamics plot (kind forwarded to :func:plot_dynamics, defaults to "phaseplane"), while a right panel shows :meth:plot_3d once with a moving marker that tracks the current parameter value on the equilibrium backbone.
Parameters
dynamics : Dynamics Model whose parameter is being swept. parameter : str Parameter name (must exist in dynamics.parameters and match this result’s continuation parameter). values : sequence of float Parameter values, one per frame. *dims, **plot_kwargs Forwarded to :func:tvbo.plot.dynamics.plot_dynamics. kind : str Plot kind for the left panel (default "phaseplane"). VOI : str, optional State variable plotted on the z-axis of the 3D diagram. interval : int Delay between frames in ms. figsize : (float, float) title_fmt : str Title format with {name} and {value} placeholders. marker_kwargs : dict, optional Style overrides for the moving marker. simulation : bool If true, overlay a trajectory computed with :class:tvbo.classes.experiment.SimulationExperiment for each frame. This keeps animated trajectories on the same backend path as full experiments instead of using Dynamics.run. simulation_duration, simulation_dt : float Integration settings used when simulation is true. simulation_backend : str Backend passed to SimulationExperiment.run. simulation_initial_values : dict or callable, optional State-variable initial values used for each simulated frame. If a callable is supplied, it receives the current parameter value and returns a mapping for that frame. Returning None skips the simulated trajectory for that frame. trajectory_kwargs : dict, optional Style overrides for simulated trajectory overlays. show_periodic_orbit : bool Draw the current periodic orbit in phase-plane coordinates when a periodic-orbit ring is also available in the bifurcation panel. orbit_kwargs : dict, optional Style overrides for the phase-plane periodic-orbit circle.
Returns
matplotlib.animation.FuncAnimation
bif_legend
analysis.bifurcation.BifurcationResult.bif_legend(
ax,
tys,
labels=None,
**lgd_kwargs,
)Add a curated legend listing the selected TYs.
Mirrors ContinuationPlot.BifLegend: draws an off-screen artist per TY using the central style registry and feeds them to a single ax.legend call so the user can pin exactly which entries appear.
extract_orbit_meshes
analysis.bifurcation.BifurcationResult.extract_orbit_meshes(n_samples=40)Extract full periodic orbit solution meshes from a PO branch.
Works with BifurcationKit.jl ContResult objects that store .sol (vector of orbit solutions at each continuation step).
Parameters
n_samples : int Number of orbits to sample evenly across the branch.
Returns
list[dict] Each dict has keys: param (float), state variable names (1D arrays of the orbit trace), and t (mesh times). Returns empty list if orbit data is unavailable.
from_auto
analysis.bifurcation.BifurcationResult.from_auto(
bd,
*,
cont_name=None,
model=None,
continuation=None,
ICS=None,
periodic_orbits_raw=None,
codim2_raw=None,
workdir=None,
**kwargs,
)Wrap an AUTO-07p bifDiag (numcont backend).
Parameters
bd : auto.bifDiag The codim-1 equilibrium continuation result. codim2_raw : list, optional [(name, source_type, fp1_name, fp2_name, R_c2), …] — codim-2 fold/Hopf/BP curves produced by NumContAdapter._run_codim2_branches. Each entry is wrapped as a child BifurcationResult and attached to self.codim2_curves with metadata (_source_type, _fp2_name) that _plot_codim2 consumes.
from_bifkit
analysis.bifurcation.BifurcationResult.from_bifkit(br, **kwargs)Wrap a BifurcationKit.jl ContResult (juliacall object).
from_pycobi
analysis.bifurcation.BifurcationResult.from_pycobi(
ode,
cont_name,
*,
model=None,
state_var_names=None,
icp=1,
fp_name='param',
periodic_orbit_results=None,
codim2_results=None,
**kwargs,
)Wrap a PyRates / PyCoBi continuation by name.
All visualisation/export logic lives on this class – the adapter just hands the extracted DataFrame straight to __init__.
plot_3d
analysis.bifurcation.BifurcationResult.plot_3d(
ax=None,
ICS=None,
ICS2=None,
VOI=None,
save=None,
n_orbit_samples=40,
**kwargs,
)Plot 3D bifurcation diagram with periodic orbit surfaces.
Shows: - Codim-1 equilibrium backbone (stable=solid, unstable=dashed) - Periodic orbit tube surface with W displacement cross-sections - Codim-2 curves (Hopf/fold loci) - Special codim-2 points (BT, GH, cusp, ZH)
Axis convention
x = primary free parameter (codim-1, e.g. I) y = secondary parameter (codim-2, e.g. b) z = state variable (VOI, e.g. V)
plot_special_points
analysis.bifurcation.BifurcationResult.plot_special_points(
VOI,
ax=None,
types=None,
**kwargs,
)Mark codim-1 special points (LP/HB/BP/PD/TR/…) on ax.
Parameters
types : iterable[str], optional Restrict markers to these canonical TYs (e.g. ['LP','HB']). By default every TY found in df.specialpoint is plotted (except endpoint).
CurvePicker
analysis.bifurcation.CurvePicker(fig, result, callback=None)Click any branch line to inspect the underlying point.
Activated via BifurcationResult.enable_picker(ax, callback=...). Each branch line drawn by plot_branch carries picker=True so matplotlib raises a pick_event on click; the picker resolves the nearest df row and forwards it to callback(result, row_index).
Functions
| Name | Description |
|---|---|
| canonical_ty | Normalise any backend label to a key in BIF_STYLES. |
| get_bif_style | Look up the merged style dict for a TY (e.g. ‘LP’, ‘fold’, ‘SLC’). |
| resolve_coord | Evaluate one coord expression against df (and optionally PO meshes). |
| resolve_coords | Normalise the user’s coords argument to a tuple of arrays. |
canonical_ty
analysis.bifurcation.canonical_ty(ty)Normalise any backend label to a key in BIF_STYLES.
get_bif_style
analysis.bifurcation.get_bif_style(ty, base=None)Look up the merged style dict for a TY (e.g. ‘LP’, ‘fold’, ‘SLC’).
base defaults to the line/marker base style depending on whether the entry is a branch (no marker) or a point (marker is present).
resolve_coord
analysis.bifurcation.resolve_coord(
df,
expr,
state_var_index=None,
po_orbits=None,
)Evaluate one coord expression against df (and optionally PO meshes).
Accepts
- a column name in
df(e.g.'x','param') - a sympy-parseable expression of column names (e.g.
'V**2 + W') - a reduction call
'minmax(V)'/'avg(V)'/'norm(V)'which uses the PO orbit meshes if available, else falls back to the column itself.
Returns a pandas Series (or ndarray for minmax → shape (2, N)).
resolve_coords
analysis.bifurcation.resolve_coords(
coords,
df,
state_var_index=None,
po_orbits=None,
default_voi=None,
default_param='param',
)Normalise the user’s coords argument to a tuple of arrays.
coords accepts: * None → (param, default_voi) * 'V' → (param, V) * 'minmax(V)' → (param, [Vmin, Vmax]) * (p, V) → 2D * (p, V, W) → 3D Each element may itself be a string or already-resolved array.