Visualisation & Analysis
The lfm.viz module gives you 10 ready-made plotting functions. Two lines of code: import + call. Every function returns (fig, ax) so you can customise with standard matplotlib.
What you'll learn
- ›How to create 2D slices of 3D fields with
plot_slice - ›Radial profiles with automatic 1/r reference overlay
- ›Time-evolution dashboards from
sim.history - ›Fourier power spectrum P(k) analysis
- ›Parameter sweeps: vary amplitude and plot the effect on χ_min
Install
pip install "lfm-physics[viz]"This adds matplotlib as a dependency. The core library works without it.
Full script
"""15 – Visualisation & Analysis
The lfm.viz toolkit: plot slices, radial profiles, time-series
dashboards, power spectra, and parameter sweeps without writing
any matplotlib boilerplate.
Requires: pip install "lfm-physics[viz]"
"""
import lfm
# ── 1. Run a quick simulation ─────────────────────────────────────────
config = lfm.SimulationConfig(grid_size=32)
sim = lfm.Simulation(config)
sim.place_soliton((16, 16, 16), amplitude=6.0)
sim.equilibrate()
sim.run(steps=3000)
print("15 – Visualisation & Analysis")
print("=" * 55)
print()
m = sim.metrics()
print(f" chi_min = {m['chi_min']:.2f} (gravity well depth)")
print(f" wells = {m['well_fraction']*100:.1f}%")
print()
# ── 2. 2D slice through the chi field ─────────────────────────────────
from lfm.viz import plot_slice, plot_three_slices
fig, ax = plot_slice(sim.chi, axis=2, index=16, title="χ mid-plane (z=16)")
fig.savefig("tutorial_15_slice.png", dpi=120, bbox_inches="tight")
print("Saved: tutorial_15_slice.png")
# Three-panel overview (XY, XZ, YZ)
fig = plot_three_slices(sim.chi, title="χ field — three planes")
fig.savefig("tutorial_15_three_slices.png", dpi=120, bbox_inches="tight")
print("Saved: tutorial_15_three_slices.png")
# ── 3. Radial profile with 1/r reference ──────────────────────────────
from lfm.viz import plot_radial_profile
fig, ax = plot_radial_profile(sim.chi, center=(16, 16, 16), max_radius=12)
fig.savefig("tutorial_15_radial.png", dpi=120, bbox_inches="tight")
print("Saved: tutorial_15_radial.png")
# ── 4. Chi histogram ──────────────────────────────────────────────────
from lfm.viz import plot_chi_histogram
fig, ax = plot_chi_histogram(sim.chi, title="χ distribution after 3000 steps")
fig.savefig("tutorial_15_histogram.png", dpi=120, bbox_inches="tight")
print("Saved: tutorial_15_histogram.png")
# ── 5. Time-evolution dashboard ───────────────────────────────────────
from lfm.viz import plot_evolution
fig = plot_evolution(sim.history, title="Metric evolution")
fig.savefig("tutorial_15_evolution.png", dpi=120, bbox_inches="tight")
print("Saved: tutorial_15_evolution.png")
# ── 6. Fourier power spectrum ─────────────────────────────────────────
from lfm.viz import plot_power_spectrum
fig, ax = plot_power_spectrum(sim.chi, title="P(k) of χ field")
fig.savefig("tutorial_15_spectrum.png", dpi=120, bbox_inches="tight")
print("Saved: tutorial_15_spectrum.png")
# ── 7. Parameter sweep ───────────────────────────────────────────────
from lfm.viz import plot_sweep
sweep_cfg = lfm.SimulationConfig(grid_size=32)
results = lfm.sweep(
sweep_cfg,
param="amplitude",
values=[2, 4, 6, 8],
steps=2000,
metric_names=["chi_min", "well_fraction"],
)
fig, ax = plot_sweep(results, x_param="amplitude", y_metric="chi_min",
title="χ_min vs soliton amplitude")
fig.savefig("tutorial_15_sweep.png", dpi=120, bbox_inches="tight")
print("Saved: tutorial_15_sweep.png")
print()
print("All plots saved. Open the PNG files to explore your simulation.")
print("Every lfm.viz function returns (fig, ax) so you can customise further.")Step-by-step walkthrough
Step 1 — Run a simulation
config = lfm.SimulationConfig(grid_size=32)
sim = lfm.Simulation(config)
sim.place_soliton((16, 16, 16), amplitude=6.0)
sim.equilibrate()
sim.run(steps=3000)Standard setup: 32³ lattice, one soliton at the centre. After 3000 steps the χ-well has formed and the energy has redistributed.
Step 2 — Slice the χ field
from lfm.viz import plot_slice
fig, ax = plot_slice(sim.chi, axis=2, index=16)plot_slice extracts a 2D plane from the 3D field. axis=2 means “cut along z”,index=16 picks the mid-plane. The red-blue colourmap shows χ < 19 (wells) in blue and χ ≈ 19 (vacuum) in white.
Step 3 — Radial profile
from lfm.viz import plot_radial_profile
fig, ax = plot_radial_profile(sim.chi, center=(16,16,16))Azimuthally averages χ(r) and overlays a best-fit 1/r curve (dashed). If the soliton creates Newtonian-like gravity, the two curves should track closely.
Step 4 — Evolution dashboard
from lfm.viz import plot_evolution
fig = plot_evolution(sim.history)Reads the metric snapshots stored in sim.historyand creates a multi-panel time-series. By default it plots chi_min,well_fraction, and energy_total if available.
Step 5 — Power spectrum
from lfm.viz import plot_power_spectrum
fig, ax = plot_power_spectrum(sim.chi)Computes the radially-averaged Fourier power P(k) of the χ field. A localised soliton produces a smooth P(k); cosmic structure shows distinct peaks.
Step 6 — Parameter sweep
results = lfm.sweep(config, param="amplitude",
values=[2, 4, 6, 8], steps=2000)
from lfm.viz import plot_sweep
fig, ax = plot_sweep(results, "amplitude", "chi_min")lfm.sweep() runs one simulation per amplitude value and records the final metrics.plot_sweep() then plots χ_min vs amplitude. Higher amplitude → deeper well → lower χ_min.
Expected output
15 – Visualisation & Analysis ======================================================= chi_min = 15.23 (gravity well depth) wells = 4.2% Saved: tutorial_15_slice.png Saved: tutorial_15_three_slices.png Saved: tutorial_15_radial.png Saved: tutorial_15_histogram.png Saved: tutorial_15_evolution.png Saved: tutorial_15_spectrum.png Saved: tutorial_15_sweep.png All plots saved. Open the PNG files to explore your simulation. Every lfm.viz function returns (fig, ax) so you can customise further.
All 10 lfm.viz functions
| Function | Purpose | Returns |
|---|---|---|
| plot_slice | 2D slice through a 3D field | (fig, ax) |
| plot_three_slices | XY + XZ + YZ panels | fig |
| plot_chi_histogram | Distribution of χ values | (fig, ax) |
| plot_evolution | Multi-panel time-series dashboard | fig |
| plot_energy_components | Stacked kinetic / gradient / potential | (fig, ax) |
| plot_radial_profile | χ(r) with 1/r reference | (fig, ax) |
| plot_isosurface | 3D voxel rendering | fig |
| plot_power_spectrum | Fourier P(k) plot | (fig, ax) |
| plot_trajectories | Peak motion scatter plot | (fig, ax) |
| plot_sweep | Sweep results line plot | (fig, ax) |
Every function accepts an optional ax= parameter so you can embed it in your own subplot grid.
Composable design
All lfm.viz functions return standard matplotlib objects. You can combine them freely: create a 2×2 grid of subplots, pass eachax into a different function, then save the combined figure. No magic, no hidden state.