Results: layout, files, and how to read them

Nothing computes and plots in one step. Solvers/scripts call storage.save_run to write a structured dict file; plotting.py is a pure consumer that reads those files and draws figures. So any figure can be regenerated from a saved run without recomputing.

Directory layout

results/
  <env>/<solver>.{json,npz,png}     # one training run (scripts/run.py)
  sweeps/<env>_sweep_N.{json,png}      # N-sweep (scripts/sweep_N.py)
  surfaces/<env>_surface_delay_nu.{json,png}  # 3-D surface (scripts/surface_delay_nu.py)
  compare/comparison.{json,md}         # the comparison table (scripts/compare.py)

The run-file schema (JSON)

Every stored run is a dict with four sections. Small values live in the readable .json; bulky arrays are offloaded to a sidecar .npz and stitched back by storage.load_run.

{
  "config":  {env, solver, N, seeds, horizon, iters, nu, delay, ...},  # what was run
  "metrics": {final_return, random, oracle, ...},   # scalar summaries
  "curves":  {return_curve: [...], ...},            # arrays over iterations / N / grid
  "meta":    {timestamp, note, ...}                 # free-form
}

The numbers

How to read each figure

figureaxeswhat to look for
<env>/<solver>.pngreward vs iteration the learning curve rising between the random and oracle lines
sweeps/..._sweep_N.pngreward vs N static stays flat; under the wall the oracle sinks toward random as N grows
surfaces/..._surface_delay_nu.pngreward over (delay, drift), per N the surface caves in as either axis increases, and deeper at larger N

The comparison table

results/compare/comparison.md is a Markdown table, rows = (env, N), columns = random, oracle, then each solver's final return and its p. It is regenerable and version-controllable — the baselines table to grow as solvers are added.

Loading results in Python

from coadapt.storage import load_run
from coadapt.plotting import plot_learning_curve
run = load_run("results/relay_discrete/ppo.json")
print(run["metrics"])                       # {'final_return':..., 'random':..., 'oracle':...}
plot_learning_curve(run, "out.png")         # redraw from the saved run