visualization.PhasePortraitPlotter
visualization.PhasePortraitPlotter(backend='numpy', default_theme='default')Phase space visualization for dynamical systems.
Provides interactive Plotly-based plotting for phase portraits in 2D and 3D, with optional vector fields, equilibrium points, and direction indicators.
Attributes
| Name | Type | Description |
|---|---|---|
| backend | Backend | Default computational backend for array conversion |
| default_theme | str | Default plot theme to apply |
Examples
2D phase portrait:
>>> plotter = PhasePortraitPlotter()
>>> x = np.column_stack([np.sin(t), np.cos(t)]) # (T, 2)
>>> fig = plotter.plot_2d(x, state_names=('sin', 'cos'))
>>> fig.show()With vector field and equilibrium:
>>> def f(x1, x2):
... return np.array([x2, -x1 - 0.1*x2])
>>>
>>> fig = plotter.plot_2d(
... x,
... vector_field=f,
... equilibria=[np.zeros(2)],
... show_direction=True,
... theme='publication'
... )3D phase portrait (Lorenz attractor):
>>> fig = plotter.plot_3d(
... x_lorenz, # (T, 3)
... state_names=('x', 'y', 'z'),
... color_scheme='tableau',
... theme='dark'
... )Methods
| Name | Description |
|---|---|
| list_available_color_schemes | List available color schemes. |
| list_available_themes | List available plot themes. |
| plot_2d | Create 2D phase portrait (x₂ vs x₁). |
| plot_3d | Create 3D phase portrait. |
| plot_limit_cycle | Visualize limit cycle (periodic orbit). |
list_available_color_schemes
visualization.PhasePortraitPlotter.list_available_color_schemes()List available color schemes.
Returns
| Name | Type | Description |
|---|---|---|
| List[str] | Available color scheme names |
Examples
>>> schemes = PhasePortraitPlotter.list_available_color_schemes()
>>> print(schemes)
['plotly', 'd3', 'colorblind_safe', 'tableau', ...]list_available_themes
visualization.PhasePortraitPlotter.list_available_themes()List available plot themes.
Returns
| Name | Type | Description |
|---|---|---|
| List[str] | Available theme names |
Examples
>>> themes = PhasePortraitPlotter.list_available_themes()
>>> print(themes)
['default', 'publication', 'dark', 'presentation']plot_2d
visualization.PhasePortraitPlotter.plot_2d(
x,
state_names=('x₁', 'x₂'),
trajectory_names=None,
show_direction=True,
show_start_end=True,
vector_field=None,
equilibria=None,
title='2D Phase Portrait',
color_scheme='plotly',
theme=None,
**kwargs,
)Create 2D phase portrait (x₂ vs x₁).
Plots trajectory through 2D state space with optional vector field overlay and equilibrium point markers.
Parameters
| Name | Type | Description | Default |
|---|---|---|---|
| x | np.ndarray | State trajectory, shape (T, 2) or (n_batch, T, 2) Must be 2-dimensional state | required |
| state_names | Tuple[str, str] | Names for horizontal and vertical axes Default: (‘x₁’, ‘x₂’) | ('x₁', 'x₂') |
| trajectory_names | Optional[List[str]] | Custom names for each trajectory (for batched trajectories) If None, uses “Trajectory 1”, “Trajectory 2”, etc. Length must equal number of batches | None |
| show_direction | bool | If True, add arrows showing trajectory direction | True |
| show_start_end | bool | If True, mark initial and final points | True |
| vector_field | Optional[Callable] | Function f(x1, x2) -> [dx1, dx2] for vector field If provided, overlays arrow field showing dynamics | None |
| equilibria | Optional[List[np.ndarray]] | List of equilibrium points to mark, each shape (2,) | None |
| title | str | Plot title | '2D Phase Portrait' |
| color_scheme | str | Color scheme name Options: ‘plotly’, ‘d3’, ‘colorblind_safe’, ‘tableau’, ‘sequential_blue’, ‘diverging_red_blue’, etc. Default: ‘plotly’ | 'plotly' |
| theme | Optional[str] | Plot theme to apply Options: ‘default’, ‘publication’, ‘dark’, ‘presentation’ If None, uses self.default_theme | None |
| **kwargs | Additional customization arguments | {} |
Returns
| Name | Type | Description |
|---|---|---|
| go.Figure | Plotly figure object |
Examples
>>> # Simple phase portrait
>>> t = np.linspace(0, 10, 100)
>>> x = np.column_stack([np.sin(t), np.cos(t)])
>>> fig = plotter.plot_2d(x, state_names=('Position', 'Velocity'))
>>> fig.show()
>>>
>>> # With vector field (pendulum) and publication theme
>>> def pendulum_dynamics(x1, x2):
... return np.array([x2, -np.sin(x1) - 0.1*x2])
>>>
>>> fig = plotter.plot_2d(
... x,
... vector_field=pendulum_dynamics,
... equilibria=[np.array([0, 0]), np.array([np.pi, 0])],
... show_direction=True,
... color_scheme='colorblind_safe',
... theme='publication'
... )
>>>
>>> # Batched trajectories (multiple initial conditions)
>>> x_batch = np.random.randn(5, 100, 2)
>>> fig = plotter.plot_2d(
... x_batch,
... trajectory_names=['IC 1', 'IC 2', 'IC 3', 'IC 4', 'IC 5'],
... theme='dark'
... )Notes
- Automatically handles batched trajectories
- Vector field computed on grid if provided
- Start point: green circle, End point: red square
- Direction arrows added at regular intervals
plot_3d
visualization.PhasePortraitPlotter.plot_3d(
x,
state_names=('x₁', 'x₂', 'x₃'),
trajectory_names=None,
show_direction=True,
show_start_end=True,
title='3D Phase Portrait',
color_scheme='plotly',
direction_colorscale='Viridis',
theme=None,
**kwargs,
)Create 3D phase portrait.
Plots trajectory through 3D state space with interactive rotation.
Parameters
| Name | Type | Description | Default |
|---|---|---|---|
| x | np.ndarray | State trajectory, shape (T, 3) or (n_batch, T, 3) Must be 3-dimensional state | required |
| state_names | Tuple[str, str, str] | Names for x, y, z axes Default: (‘x₁’, ‘x₂’, ‘x₃’) | ('x₁', 'x₂', 'x₃') |
| trajectory_names | Optional[List[str]] | Custom names for each trajectory (for batched trajectories) If None, uses “Trajectory 1”, “Trajectory 2”, etc. Length must equal number of batches | None |
| show_direction | bool | If True, show temporal direction via line color gradient (single trajectory only) | True |
| show_start_end | bool | If True, mark initial and final points | True |
| title | str | Plot title | '3D Phase Portrait' |
| color_scheme | str | Color scheme name Options: ‘plotly’, ‘d3’, ‘colorblind_safe’, ‘tableau’, etc. Default: ‘plotly’ Note: Only used for batched trajectories; single trajectories use direction_colorscale | 'plotly' |
| direction_colorscale | str | Colorscale for temporal gradient (single trajectory only) Options: ‘Viridis’, ‘Plasma’, ‘Inferno’, ‘Magma’, ‘Cividis’, ‘Turbo’, ‘Rainbow’, ‘Jet’, ‘Hot’, ‘Cool’, ‘Blues’, ‘Reds’, ‘Greens’, ‘Portland’, ‘Picnic’, ‘Electric’, ‘Blackbody’ Default: ‘Viridis’ | 'Viridis' |
| theme | Optional[str] | Plot theme to apply Options: ‘default’, ‘publication’, ‘dark’, ‘presentation’ If None, uses self.default_theme | None |
| **kwargs | Additional customization arguments | {} |
Returns
| Name | Type | Description |
|---|---|---|
| go.Figure | Interactive 3D Plotly figure |
Examples
>>> # Lorenz attractor with temporal gradient
>>> x_lorenz = solve_lorenz(...) # (T, 3)
>>> fig = plotter.plot_3d(
... x_lorenz,
... state_names=('x', 'y', 'z'),
... title='Lorenz Attractor',
... show_direction=True,
... theme='dark'
... )
>>> fig.show()
>>>
>>> # Multiple trajectories with custom names
>>> x_batch = np.random.randn(3, 1000, 3)
>>> fig = plotter.plot_3d(
... x_batch,
... trajectory_names=['Low Energy', 'Medium Energy', 'High Energy'],
... color_scheme='colorblind_safe',
... theme='publication'
... )Notes
- Interactive: Click and drag to rotate
- Scroll to zoom
- Single trajectory: Line color shows time progression (dark→light)
- Batched trajectories: Each trajectory has distinct solid color
- Start: green sphere, End: red cube
plot_limit_cycle
visualization.PhasePortraitPlotter.plot_limit_cycle(
x,
state_names=('x₁', 'x₂'),
trajectory_names=None,
period_estimate=None,
title='Limit Cycle',
color_scheme='plotly',
theme=None,
**kwargs,
)Visualize limit cycle (periodic orbit).
Highlights periodic behavior in phase space by overlaying multiple periods if detected.
Parameters
| Name | Type | Description | Default |
|---|---|---|---|
| x | np.ndarray | State trajectory, shape (T, 2) Should contain at least one full period | required |
| state_names | Tuple[str, str] | Names for axes | ('x₁', 'x₂') |
| trajectory_names | Optional[List[str]] | Custom names for trajectories If None, uses “Trajectory 1” | None |
| period_estimate | Optional[float] | Estimated period (in samples) If None, attempts auto-detection | None |
| title | str | Plot title | 'Limit Cycle' |
| color_scheme | str | Color scheme name Default: ‘plotly’ | 'plotly' |
| theme | Optional[str] | Plot theme to apply Options: ‘default’, ‘publication’, ‘dark’, ‘presentation’ If None, uses self.default_theme | None |
| **kwargs | Additional arguments | {} |
Returns
| Name | Type | Description |
|---|---|---|
| go.Figure | Phase portrait with limit cycle highlighted |
Examples
>>> # Van der Pol oscillator
>>> x_vdp = solve_van_der_pol(...) # (T, 2)
>>> fig = plotter.plot_limit_cycle(
... x_vdp,
... period_estimate=100,
... theme='publication'
... )
>>> fig.show()Notes
- Limit cycle detection is heuristic
- Works best with long trajectories (many periods)
- Highlights the periodic attractor