Skip to content

Visualization

The seven algorithms KD supports work in different ways: a population of expression trees, a neural network paired with a genetic search, a policy network emitting expressions symbol by symbol, a pretrained Transformer, rounds of proposals from a large language model, a one-shot sparse regression over a candidate library. Looking at any of them is the same call: hand the fitted result to kd.VizEngine and one call renders the whole set of figures. Switch algorithm= and the figures follow, with nothing new to learn about how to read them. This page is the gallery; Figure generation covers how to render them for your own run.

Platform figures

Whichever algorithm ran, VizEngine draws the same group: best score per iteration, measured against predicted, the equation typeset and as a structure tree, the fitted coefficients, and the residual as a histogram and as a spatial map. Pass the dataset as well and it adds the field comparison, the u_t residual field, time slices and an error heatmap.

The six figures below come from one run: SGA-PDE on the KdV dataset that ships with KD, 200 generations, seed 42.

Heatmap of the KdV field u(x, t)
The observed field u(x, t) of the KdV dataset. Every other figure on this page is computed against it.
Measured u_t, predicted u_t, and the residual between them
The discovered equation evaluated against the data: measured u_t on the left, the equation's u_t in the middle on a shared color scale, their difference on the right. The nmse of this run is 2.7e-06.
Predicted u_t against measured u_t, with a 45-degree reference line
The same agreement as a scatter: all 51,456 grid points against the 45-degree line, at an R² of 0.999997. This figure is read the same way for every algorithm and every equation.
Best AIC and population mean AIC per generation
The convergence curve. The solid line is the best score per generation, an AIC for this run, where lower is better, settling at −19.42 by generation 9. The dashed line is the same run's population mean, which keeps moving after the best has settled.
Bar chart of the two fitted coefficients on a symmetric log axis
The fitted coefficients on a symmetric log axis, since the two span two decades: −0.0025 on u_xxx and −0.5 on (u²)_x, which is the same law as −u u_x. The bars carry the algorithm's own coefficients rather than a platform refit.
The discovered equation drawn as an expression tree
The answer as a structure tree: six nodes over four rows, with the coefficients left off, so the figure shows the shape of the equation rather than its magnitudes. Equation representation covers the notation.

One call renders all 15 of them into a single HTML file, every figure inlined as SVG, together with the run's settings and its full result as JSON. The one from the configuration above is published here: example report (1.7 MB).

Algorithm panels

The group above answers whether the result is right; an algorithm's own panels answer how it got there, so each algorithm declares and draws its own:

  • SGA-PDE, DLGA-PDE: population-level records, per generation the diversity of the candidates, the term count of the candidate equations and the score spread of the survivors, plus the training loss of the neural-network surrogate (filled in only when the platform trained one). SGA-PDE also draws the genome tree of its best individual.
  • DISCOVER: the policy network's training record, per iteration the reward (one curve for the elite subset, one for the full batch), the entropy regularizer and the reward baseline.
  • EqGPT: the reward of the candidate pool per epoch and its spread, plus the cross-entropy loss of each epoch's fine-tune. In multi-case mode it adds the reward of the discovered structure on every case.
  • LLM4ED: the reward spread of the candidate pool per round, the count of invalid candidates, and the cumulative number of language-model calls.
  • PySR: the Pareto front (complexity against loss), KD's independent re-score of that same front, and the two scores against each other.
  • PySINDy: one comparison figure putting the NMSE of PySINDy's native coefficients next to the NMSE of KD's independent refit.

Each row below is one algorithm's panels, from that algorithm's own worked run.

SGA-PDE offspring diversity, complexity evolution and fitness spread
SGA-PDE on KdV: distinct candidate expressions per generation, mean term count, and mean AIC of the surviving population.
DLGA-PDE population diversity, complexity evolution and fitness spread
DLGA-PDE on Burgers: the same three panels from a different algorithm. The fitness axis is logarithmic, so the one generation whose mean is carried into the thousands by an ill-conditioned candidate stays readable.
DISCOVER reward curves and entropy loss
DISCOVER on Chafee-Infante: reward of the top 2% of draws, reward over the whole batch of 500, and the entropy regularizer. A policy-gradient search records the state of the network rather than the contents of a population.
EqGPT pool reward spread and fine-tuning loss
EqGPT on Burgers: the reward band of the elite pool, best against median against worst, and the cross-entropy loss of each epoch's fine-tune on that pool.
LLM4ED pool reward spread, invalid proposals and cumulative calls
LLM4ED on the heat dataset: the pool's reward band, the proposals per round that failed to parse or to solve, and and the running total of endpoint calls, which tracks the run's budget.

Data shape

Which figures a run gets follows from the shape of its data rather than from the algorithm. Data on a regular grid gets the whole set. Scattered measurements carry point coordinates and no grid, so the field family is left out and the rest draws as usual; the breaking-waves example is a run of that kind. A table of X against y has no field at all, and the coefficient bar follows whether the run returned an equation rather than on the shape of the data. Two-dimensional space plus time adds one more: pass animate=True and render_all writes a GIF of the field evolving.

Whatever is left out is named in report.warnings, one note per figure family, and the same notes appear on the report page.

Figure index

Every figure KD draws, and the call that draws just that one. The platform half runs for any result; the rest belong to the algorithm named beside them. Two are composed at render time and are not listed: SGA-PDE's genome tree, and EqGPT's panels in multi-case and steady mode. At run time plugin.list_plots() returns the complete set for the algorithm that ran.

Figure Call Owner
Coefficient bar kd.viz.plots.plot_coefficient_bar(result, ax) platform
Convergence kd.viz.plots.plot_convergence(result, ax) platform
Equation kd.viz.plots.plot_equation(result, ax) platform
Equation tree kd.viz.plots.plot_equation_tree(result, ax) platform
Error heatmap kd.viz.plots.plot_error_heatmap(dataset, integration_result) platform
Field animation kd.viz.plots.plot_field_animation(dataset, integration_result) platform
Field comparison kd.viz.plots.plot_field_comparison(dataset, integration_result) platform
Parity kd.viz.plots.plot_parity(result, ax) platform
Pde residual field kd.viz.plots.plot_pde_residual_field(result) platform
Residual kd.viz.plots.plot_residual(result) platform
Score bar kd.viz.plots.plot_score_bar(results, ax) platform
Summary table kd.viz.plots.plot_summary_table(results, ax) platform
Time slices kd.viz.plots.plot_time_slices(dataset, integration_result) platform
Overlaid convergence kd.viz.plots.render_overlaid_convergence(results, ax) platform
Offspring Diversity plugin.render_plot("population_diversity", ax) SGA-PDE
Complexity Evolution plugin.render_plot("complexity_evolution", ax) SGA-PDE
Fitness Spread plugin.render_plot("fitness_spread", ax) SGA-PDE
Surrogate Training Curve plugin.render_plot("surrogate_training", ax) SGA-PDE
Fitness Spread plugin.render_plot("fitness_spread", ax) DLGA-PDE
Population Diversity plugin.render_plot("population_diversity", ax) DLGA-PDE
Complexity Evolution plugin.render_plot("complexity_evolution", ax) DLGA-PDE
Surrogate Training Curve plugin.render_plot("surrogate_training", ax) DLGA-PDE
Reward (Mean of Top ε) plugin.render_plot("reward_convergence", ax) DISCOVER
Reward (Full-Batch Mean) plugin.render_plot("reward_full_mean", ax) DISCOVER
Entropy Loss plugin.render_plot("entropy_loss_decay", ax) DISCOVER
Reward Baseline plugin.render_plot("baseline_ewma", ax) DISCOVER
Reward Convergence plugin.render_plot("reward_convergence", ax) EqGPT
Pool Reward Spread plugin.render_plot("pool_reward_spread", ax) EqGPT
Fine-tune Loss plugin.render_plot("finetune_loss", ax) EqGPT
Pool Reward Spread plugin.render_plot("pool_reward_spread", ax) LLM4ED
Invalid Count plugin.render_plot("invalid_count", ax) LLM4ED
Cumulative LLM Calls plugin.render_plot("llm_calls", ax) LLM4ED
Pareto Front plugin.render_plot("pareto_front", ax) PySR
kd Audit Path plugin.render_plot("kd_audit_path", ax) PySR
Score Agreement plugin.render_plot("score_agreement", ax) PySR
Native vs Refit NMSE plugin.render_plot("native_refit_agreement", ax) PySINDy