SFI.utils.plotting module¶
- SFI.utils.plotting.SFI_COLORS = {'bootstrap': '#5D3A9B', 'data': '#3B9EFF', 'error': '#FF2D6F', 'exact': '#FF7A1A', 'highlight': '#40B0A6', 'inferred': '#FFC20A', 'secondary': '#1A85FF', 'tertiary': '#D35FB7'}¶
Named colour palette for consistent plotting across gallery examples and user notebooks. Adjusted for readability on both dark (#131416) and light backgrounds.
- SFI.utils.plotting.animate_particles(coll, *, dataset=0, dims=(0, 1), trail=0, overlay_fn=None, skip=1, cmap='magma', s=100.0, color_dim=None, vmin=None, vmax=None, quiver=False, heading_dim=None, box=None, interval=50, ax=None, fig=None, blit=False, **anim_kw)[source]¶
Animate particle positions over time (frames read via the collection).
Returns a
matplotlib.animation.FuncAnimation. Withtrail>0each particle leaves a fading tail;overlay_fn(ax, t_index, X_t)is called per frame for custom overlays. For active matter, color points by a state dimension (color_dim, e.g. heading angle), overlay heading arrows (quiver=True+heading_dim), and wrap into a periodic box (box=(Lx, Ly)) — mirroringplot_particles().- Parameters:
coll (TrajectoryCollection)
dataset (int)
trail (int)
skip (int)
cmap (str)
s (float)
quiver (bool)
interval (int)
blit (bool)
- SFI.utils.plotting.animate_spde_comparison(coll_a, coll_b, *, dataset=0, field_component=0, grid_shape=None, skip=1, vmin=None, vmax=None, cmap='magma', titles=('A', 'B'), interval=50, plot_colorbar=True, blit=False, **anim_kw)[source]¶
Side-by-side animation of one channel of two gridded collections.
Returns a
matplotlib.animation.FuncAnimationwith two image panels sharing color limits (e.g. data vs bootstrap SPDE fields).- Parameters:
coll_a (TrajectoryCollection)
coll_b (TrajectoryCollection)
dataset (int)
field_component (int)
skip (int)
cmap (str)
interval (int)
plot_colorbar (bool)
blit (bool)
- SFI.utils.plotting.axisvector(index, dim)[source]¶
d-dimensional unit vector pointing in direction index.
- SFI.utils.plotting.comparison_scatter(Xexact, Xinferred, error=None, maxpoints=10000, vmax=None, color=None, alpha=0.05, y=0.8, mode='both', fontsize=9)[source]¶
This method is used to compare inferred components to the exact ones along the trajectory, in a graphical way.
Xexact, Xinferred: jnp arrays (Nsteps,…); must have the same shape.
error: predicted standard deviation for X_inferred.
maxpoints: if Nsteps / 2 * maxpoints, data will be subsampled.
- SFI.utils.plotting.dark_ax(ax)[source]¶
Style a matplotlib Axes for a dark background.
Sets black face colour, white ticks and labels, and dark-grey spines.
- SFI.utils.plotting.dark_fig(nrows=1, ncols=1, **kw)[source]¶
Create a figure and axes with a black background.
All arguments are forwarded to
plt.subplots. Returns(fig, axes)likeplt.subplots.
- SFI.utils.plotting.phase2d(coll, *, dataset=0, dims=None, dir1=None, dir2=None, shift=(0.0, 0.0), tmin=None, tmax=None, particles=None, cmap='viridis', linewidth=1.5, alpha=1.0, plot_colorbar=False, box=None, transform=None, color=None, ax=None, drop_masked=True)[source]¶
2D phase-space plot with connected line segments colored along the trajectory.
- Parameters:
coll (TrajectoryCollection) – TrajectoryCollection containing the data.
dataset (int) – Dataset index inside the collection.
dims – Pair of coordinate indices (i, j) to plot. Ignored if
dir1/dir2are provided. If None and no directions are given, defaults to (0, 1).dir1 – Optional projection directions in R^d. If given, positions are projected onto these directions instead of using coordinate axes.
dir2 – Optional projection directions in R^d. If given, positions are projected onto these directions instead of using coordinate axes.
shift – (xshift, yshift) added to all positions.
tmin – Integer time-index bounds. If None, full range is used. Negative
tmaxis interpreted as from the end.tmax – Integer time-index bounds. If None, full range is used. Negative
tmaxis interpreted as from the end.particles – Sequence of particle indices to include. If None, include all.
cmap – Colormap for the time-coloring.
linewidth (float) – Line width of the trajectory segments.
alpha (float) – Global alpha for the line collection.
plot_colorbar (bool) – If True, add a colorbar for the time coloring.
box – Optional periodic box
(Lx, Ly). If given, positions are wrapped modulo the box and segments that cross a boundary are dropped, so trajectories render correctly in a periodic domain.transform – Optional callable applied elementwise to the projected
xandy(e.g.np.expto map a log-space coordinate back to population space). Applied after projection/shift/box-wrap.color – Optional single color. If given, draw the trajectory in this solid color instead of the time-colored gradient (incompatible with
plot_colorbar).ax – Optional Matplotlib Axes. If None, use
plt.gca().drop_masked (bool) – If True, drop segments where either endpoint is masked.
- Returns:
The created
matplotlib.collections.LineCollection.- Return type:
lc
- SFI.utils.plotting.phase2d_scalar(coll, *, color_fn, dataset=0, dims=(0, 1), tmin=None, tmax=None, particles=None, cmap='plasma', linewidth=1.5, alpha=1.0, plot_colorbar=True, colorbar_label='', ax=None, drop_masked=True)[source]¶
2D phase-space plot colored by a scalar field of the coordinate.
Like
phase2d(), but each segment is colored bycolor_fn(midpoint)rather than by time — e.g. the local diffusivityD(x), the speed, or a potential.color_fnreceives the full d-dimensional segment midpoints, shape(n_segments, d), and must return a scalar per segment, shape(n_segments,).- Parameters:
coll (TrajectoryCollection)
dataset (int)
linewidth (float)
alpha (float)
plot_colorbar (bool)
colorbar_label (str)
drop_masked (bool)
- Return type:
LineCollection
- SFI.utils.plotting.phase3d(coll, *, dataset=0, dims=(0, 1, 2), tmin=None, tmax=None, particles=None, cmap='viridis', linewidth=1.5, alpha=1.0, scatter_endpoints=True, scatter_size=30.0, ax=None, drop_masked=True)[source]¶
3D trajectory plot with segments colored along time.
The 3D analog of
phase2d(): draws each particle’s path as a time-coloredLine3DCollection. Pass a 3D axes viaaxor a new one is created (projection="3d").- Parameters:
coll (TrajectoryCollection)
dataset (int)
linewidth (float)
alpha (float)
scatter_endpoints (bool)
scatter_size (float)
drop_masked (bool)
- SFI.utils.plotting.plot_field(coll, field, *, dataset=0, dir1=None, dir2=None, center=None, N=10, scale=1.0, autoscale=False, color='g', radius=None, positions=None, powernorm=0.0, mask_unvisited=False, clip_magnitude=None, **kwargs)[source]¶
Plot a 2D vector field (or a 2D slice of a higher-dimensional field).
- Parameters:
coll (TrajectoryCollection) – TrajectoryCollection providing typical positions for scaling/centering.
field – Callable
field(X) -> Fwith X of shape (n_points, d) and F of same shape.dataset (int) – Dataset index inside the collection used to estimate center/radius.
dir1 – Projection directions in R^d. If None, use coordinate axes 0 and 1.
dir2 – Projection directions in R^d. If None, use coordinate axes 0 and 1.
center – Grid / scaling controls.
N (int) – Grid / scaling controls.
scale (float) – Grid / scaling controls.
autoscale (bool) – Grid / scaling controls.
color – Grid / scaling controls.
radius – Grid / scaling controls.
positions – Grid / scaling controls.
powernorm (float) – Grid / scaling controls.
**kwargs – Grid / scaling controls.
mask_unvisited (bool) – If True, drop arrows in grid cells with no trajectory data within one grid spacing (keeps the quiver legible in sparsely-sampled regions).
clip_magnitude – If set, clip each arrow’s magnitude to this value (long arrows in high-force regions no longer dominate the plot).
- SFI.utils.plotting.plot_field_error(coll, field_inferred, field_exact, *, dataset=0, N=60, norm='l2', cmap='inferno', vmax=None, ax=None)[source]¶
2D heatmap of the pointwise force-reconstruction error.
Evaluates both fields on a grid spanning the (masked) data bounding box and renders
||F_exact - F_inferred||as apcolormesh. The spatial complement tocomparison_scatter().- Parameters:
coll (TrajectoryCollection)
dataset (int)
N (int)
norm (str)
cmap (str)
- SFI.utils.plotting.plot_nematic_director(ax, Qxx, Qxy, rho, *, skip=2, scale=2.5, color='white', alpha=0.55, linewidth=0.45, **quiver_kw)[source]¶
Overlay the nematic director field of a Q-tensor on an image axes.
Given the order-parameter fields
Qxx,Qxyand densityrho(each a 2D grid), draws a headless quiver of the directorψ = ½·atan2(Qxy, Qxx)on a subsampled grid — the canonical active-nematic overlay.- Parameters:
ax – Target axes (typically holding an
imshowof the density).Qxx – 2D arrays of equal shape.
Qxy – 2D arrays of equal shape.
rho – 2D arrays of equal shape.
skip (int) – Subsampling stride for the director glyphs.
scale (float) – Glyph length (passed through to
quiverscale).color (str)
alpha (float)
linewidth (float)
- SFI.utils.plotting.plot_pareto_front(result, *, criteria=('PASTIS', 'BIC', 'AIC'), ax=None)[source]¶
Plot the Pareto front: information gain vs model size, with IC optima.
- Parameters:
result (SparsityResult) – As returned by
inf.sparsify_force().criteria (tuple of str) – Information-criterion names to mark on the plot.
ax (matplotlib Axes, optional) – If None, a new figure is created.
- Returns:
ax
- Return type:
matplotlib Axes
- SFI.utils.plotting.plot_particles(coll, a=0, b=1, t_index=-1, colored=True, active=False, u=0.35, *, dataset=0, color_dim=None, cmap=None, vmin=None, vmax=None, quiver=False, heading_dim=None, box=None, s=100.0, ax=None, quiver_kw=None, **kwargs)[source]¶
Display all particles at time index
t_indexfrom a collection.- Parameters:
a (int) – State dimensions for the x/y axes of the snapshot.
b (int) – State dimensions for the x/y axes of the snapshot.
t_index (int) – Frame index (negative counts from the end).
colored (bool) – If True (and no
color_dim), color particles by index (magma).color_dim – Color particles by the value of this state dimension instead of by index — e.g. heading angle (default colormap
"hsv").cmap – Colormap / normalisation for the coloring.
vmin – Colormap / normalisation for the coloring.
vmax – Colormap / normalisation for the coloring.
quiver (bool) – If
quiver=True, overlay heading arrows fromcos/sin(X[:, heading_dim])(heading_dimdefaults to 2, the orientation channel of an active particle).heading_dim – If
quiver=True, overlay heading arrows fromcos/sin(X[:, heading_dim])(heading_dimdefaults to 2, the orientation channel of an active particle).box – Optional periodic box
(Lx, Ly); positions are wrapped into it.active (bool) – Legacy orientation marker (a dot at
u·(cosθ, sinθ)); superseded byquiverfor active-matter snapshots.u (float) – Legacy orientation marker (a dot at
u·(cosθ, sinθ)); superseded byquiverfor active-matter snapshots.ax – Target axes (default: current axes).
coll (TrajectoryCollection)
dataset (int)
s (float)
- SFI.utils.plotting.plot_particles_field(coll, field, *, dataset=0, t_index=-1, dir1=None, dir2=None, center=None, radius=None, scale=1.0, autoscale=False, color='g', **kwargs)[source]¶
Plot a 2D vector field evaluated at particle positions at a given time.
- Parameters:
coll (TrajectoryCollection)
dataset (int)
t_index (int)
scale (float)
autoscale (bool)
- SFI.utils.plotting.plot_profile_1d(coll, field, *, exact_field=None, dataset=0, dim=0, component=None, N=200, ci=None, samples=False, ax=None, margin=0.05, label_exact='Exact', label_inferred='Inferred')[source]¶
1D profile of an inferred field, optionally overlaid on the exact one.
Evaluates
fieldon a grid spanning the data range alongdimand plots the inferred profile (gold), an optional exact overlay (orange dashes), an optional confidence band, and an optional sample histogram backdrop. The 1D analog ofplot_field()for forcesF(x)and scalar diffusion profilesD(x)/D(v).- Parameters:
field – Callables
f(X) -> array(vector(N, d)or tensor(N, d, d)).exact_fieldis optional.exact_field – Callables
f(X) -> array(vector(N, d)or tensor(N, d, d)).exact_fieldis optional.dim (int) – Coordinate axis to sweep.
component – Which output component to plot. Defaults to
dimfor a vector field and(dim, dim)for a tensor field.ci – Optional dict with
"lower"/"upper"arrays (same length as the grid) for a confidence band.samples (bool) – If True, draw a faint histogram of the data along
dimbehind the curves.coll (TrajectoryCollection)
dataset (int)
N (int)
margin (float)
label_exact (str)
label_inferred (str)
- SFI.utils.plotting.plot_recovery_bar(coeffs_inferred, support_inferred, *, coeffs_true=None, support_true=None, labels=None, stderr=None, yscale='linear', sort=False, show_pruned=False, ax=None)[source]¶
Bar chart of inferred sparse coefficients vs ground truth.
- Parameters:
coeffs_inferred (array_like) – Coefficient values for the inferred support.
support_inferred (array_like) – Indices of the selected basis functions.
coeffs_true (array_like, optional) – Ground-truth coefficients / support (paired comparison).
support_true (array_like, optional) – Ground-truth coefficients / support (paired comparison).
labels (list of str, optional) – Tick labels for basis functions.
stderr (array_like, optional) – Standard errors for the inferred coefficients (drawn as error caps).
yscale (str) – Matplotlib y-scale (
"linear"or"log"; use"log"for magnitude bars with widely varying scales).sort (bool) – If True, order bars by descending
|coefficient|.show_pruned (bool) – If True (and
labelsgiven), append faded zero-bars for basis functions outside the inferred support.ax (matplotlib Axes, optional) – If None, a new figure is created.
- Returns:
ax
- Return type:
matplotlib Axes
- SFI.utils.plotting.plot_recovery_bar_multi(coeffs_list, labels, *, coeffs_true=None, group_names=None, ax=None)[source]¶
Grouped bar chart comparing coefficients across several models.
coeffs_listis a list of coefficient vectors (one per regime / solver), each aligned tolabels. An optionalcoeffs_trueis overlaid as a step reference.
- SFI.utils.plotting.plot_recovery_matrix(true, inferred, *, row_labels=None, col_labels=None, cmap='RdBu_r', vmax=None, axes=None)[source]¶
Side-by-side
imshowof a true vs inferred parameter matrix.
- SFI.utils.plotting.plot_rods(ax, X_frame, *, angle_index=2, length=0.85, color='#d4a96a', linewidth=2.8, capstyle='round', **kwargs)[source]¶
Draw oriented rods (active-matter particles) as a
LineCollection.Each particle in
X_frame(rows(x, y, …, θ, …)) becomes a short segment of lengthlengthcentred on(x, y)and oriented atθ = X_frame[:, angle_index].- Parameters:
angle_index (int)
length (float)
color (str)
linewidth (float)
capstyle (str)
- SFI.utils.plotting.plot_spde_snapshot(coll, t_indices, *, dataset=0, scalar_channel=0, vector_channels=None, grid_shape=None, dx=None, render='imshow', streamplot_kw=None, quiver_kw=None, axes=None, vmin=None, vmax=None, cmap='magma')[source]¶
Render SPDE field snapshots from a gridded TrajectoryCollection.
Reshapes each requested frame
X[t]of shape(N, n_channels)to(*grid_shape, n_channels)and drawsscalar_channelas animshowimage, optionally overlayingvector_channelsas streamlines (render="streamplot") or arrows (render="quiver").- Parameters:
t_indices – A single frame index, or a sequence of indices (one panel each).
grid_shape –
(nx, ny)of the field grid. Inferred as a square grid when omitted.dx – Physical grid spacing (default 1.0).
vmin – Color limits; default to the 0.5/99.5 percentiles of the field.
vmax – Color limits; default to the 0.5/99.5 percentiles of the field.
coll (TrajectoryCollection)
dataset (int)
scalar_channel (int)
render (str)
cmap (str)
- SFI.utils.plotting.plot_tensor_field(coll, field, *, dataset=0, center=None, N=10, scale=1.0, autoscale=False, color='g', radius=None, positions=None, mode='eigencross', **kwargs)[source]¶
Plot a tensor field for 2D processes from a TrajectoryCollection.
mode="eigencross"(default) draws each tensor as a pair of eigen-axis arrows;mode="ellipse"draws an eigen-aligned ellipse glyph (axis lengths∝ sqrt(eigenvalue)), a clearer rendering for anisotropic diffusion fields.- Parameters:
coll (TrajectoryCollection)
dataset (int)
N (int)
scale (float)
autoscale (bool)
mode (str)
- SFI.utils.plotting.plot_time_profile_comparison(t, true_profiles, inferred_profiles, *, labels=None, axes=None)[source]¶
Plot true vs inferred time-dependent profiles (e.g. k(t), a(t)).
true_profilesandinferred_profilesare sequences of 1D arrays (one per panel);true_profilesentries may beNoneto skip the reference.labelsgives a title per panel.
- SFI.utils.plotting.spatial_acorr2d(field_2d, *, dx=1.0, n_bins=None, normalize=True)[source]¶
Radially-averaged 2D spatial autocorrelation via FFT (periodic).
Returns
(r, C)whereC(r)is the angle-averaged autocorrelation offield_2d(mean removed) at radial separationr. Assumes a periodic grid.- Parameters:
dx (float)
normalize (bool)
- SFI.utils.plotting.stamp_fig(fig=None)[source]¶
Add a discreet generation timestamp to the bottom-right of a figure.
Useful for tracking when a cached or gallery figure was last rendered. Idempotent: a figure is only stamped once.
- Parameters:
fig (matplotlib.figure.Figure, optional) – Figure to stamp. Defaults to
plt.gcf().
- SFI.utils.plotting.stamp_output()[source]¶
Print a discreet generation timestamp to stdout.
Call once per script so the timestamp appears in terminal output blocks on gallery pages and in notebook cells.
- SFI.utils.plotting.stream_field(coll, field, *, dataset=0, dir1=None, dir2=None, center=None, radius=None, N=20, density=1.0, color='#808080', ax=None, **streamplot_kw)[source]¶
Streamplot of a callable vector field over the data domain.
The streamline counterpart to
plot_field()(quiver): integratesfield(X) -> Finto flow lines on a grid spanning the data bounding box. Useful for visualising the topology of an inferred or analytic drift field.- Parameters:
coll (TrajectoryCollection)
dataset (int)
N (int)
density (float)
color (str)
- SFI.utils.plotting.timeseries(coll, *, dims=None, dataset=0, particles=None, transform=None, ax=None, **plot_kw)[source]¶
Plot x[dim](t) for one or many particles from a TrajectoryCollection.
By default, plot all dimensions for the selected particles.
- Parameters:
coll (TrajectoryCollection) – TrajectoryCollection containing the data.
dims – Iterable of state dimensions to plot. If None, plot all dims.
dataset (int) – Dataset index inside the collection (default 0).
particles – Iterable of particle indices to include. If None, include all particles.
transform – Optional callable applied elementwise to the plotted values (e.g.
np.expto map a log-space coordinate back to population space).ax – Optional Matplotlib Axes. If None, use
plt.gca().**plot_kw – Forwarded to
ax.plot.
- Returns:
Matplotlib Axes used.
- Return type:
ax
- SFI.utils.plotting.timeseries_colored(coll, *, color_fn, dataset=0, dims=None, particles=None, cmap='plasma', colorbar_label='', plot_colorbar=True, ax=None, s=4.0, alpha=1.0, rasterized=True, **scatter_kw)[source]¶
Plot
x[dim](t)as a scatter colored by a scalar field.Mask-aware time series in which each point is colored by
color_fn(X)— e.g. the local diffusivity along the trajectory.color_fnreceives points of shape(n_points, d)and returns a scalar per point. A single shared colorbar spans all series.- Parameters:
coll (TrajectoryCollection)
dataset (int)
colorbar_label (str)
plot_colorbar (bool)
s (float)
alpha (float)
rasterized (bool)
- SFI.utils.plotting.trajectory_scatter(coll, *, dataset=0, dims=(0, 1), particles=None, tmin=None, tmax=None, cmap=None, s=2.0, alpha=0.1, ax=None, drop_masked=True, **scatter_kw)[source]¶
All-frames density scatter cloud of a 2D projection.
Unlike
phase2d()(connected lines) orplot_particles()(one frame), this scatters every valid(particle, frame)position — useful for occupancy / home-range visualisations. Withcmapset, points are colored by time.- Parameters:
coll (TrajectoryCollection)
dataset (int)
s (float)
alpha (float)
drop_masked (bool)