Figure generation
Two paths: one call for the whole set, or a single panel drawn onto an Axes you
own. Both run after fit, and neither needs any recording set up in advance.
One call
import kd
dataset = kd.load_kdv()
model = kd.Model(algorithm="sga", generations=200, seed=42).fit(dataset)
viz = kd.VizEngine(output_dir="out/kdv")
report = viz.render_all(model.result_, algorithm=model.algorithm_, dataset=dataset)
print(report.report)
for path in report.figures:
print(path.name)
Output (out/kdv is created if it does not exist):
out/kdv/report.html
convergence.svg
parity.svg
equation.svg
equation_tree.svg
residual.svg
coefficient_bar.svg
field_comparison.svg
pde_residual_field.svg
time_slices.svg
error_heatmap.svg
plugin_population_diversity.svg
plugin_complexity_evolution.svg
plugin_fitness_spread.svg
plugin_surrogate_training.svg
plugin_genome_tree.svg
Three arguments to render_all decide how far it draws:
algorithm=takes the fitted algorithm itself, which draws its own diagnostic panels; those filenames carry theplugin_prefix. Leave it out and only the universal figures are rendered.dataset=decides whether the data-dependent figures are drawn: the coefficient bar chart, the field comparison, theu_tresidual field, the time slices and the error heatmap.animate=Trueadditionally writes a GIF for 2D-spatial-plus-time data, with its path inreport.data_files.
Skips and degradations go into report.warnings, so the figure set never
shrinks silently. The run above produced exactly one:
plugin plot 'surrogate_training': No data (no surrogate training logged for this run)
That line comes from the algorithm's own plotting code: this run took derivatives by finite difference, trained no surrogate network, and the panel is therefore empty.
report.report points at an HTML report with every figure inlined as SVG, so it
travels as a single file; the LaTeX in the equation block is rendered by MathJax
loaded from a public CDN. The report this page's run writes is published here:
example report, 15
figures in 1.7 MB. The style= argument of VizEngine takes extra
matplotlib rcParams and merges them over KD's defaults. To put several runs side
by side, call viz.render_comparison(results, labels=[...]): the convergence
curves are overlaid, plus a bar chart of R² across the runs and a summary table.
A single panel
To place one panel in a layout of your own, create the Axes and hand it to the algorithm:
import matplotlib.pyplot as plt
plugin = model.algorithm_
print([info.name for info in plugin.list_plots()])
fig, ax = plt.subplots(figsize=(5, 3))
plugin.render_plot("complexity_evolution", ax)
fig.savefig("complexity.png", dpi=150, bbox_inches="tight")
data = plugin.get_plot_data("complexity_evolution")
print(data["ylabel"], data["y"][:5])
Output:
['population_diversity', 'complexity_evolution', 'fitness_spread', 'surrogate_training', 'genome_tree']
gen_mean_complexity [1.8235294117647058, 2.34375, 3.242424242424242, 3.026315789473684, 3.6]
The Figure belongs to the caller: render_plot draws only on the Axes it is
given, so size, colors and titles remain under the caller's control. It returns
the degradation notes for that panel (no data, gaps in the series), and merging
those into report.warnings is what render_all does with them.
get_plot_data returns the numbers behind the same panel, ready to serialize to
JSON and hand to another plotting library or keep as a record. Its fields depend
on the panel; a per-generation curve is {x, y, xlabel, ylabel, title}.
An unknown name raises, listing the names this algorithm has:
Unknown plot name: 'nope'. Available: population_diversity, complexity_evolution, fitness_spread, surrogate_training, genome_tree
For another algorithm, change algorithm= and re-run: list_plots() then
returns that algorithm's panels, and both paths above are written the same way.