Skip to content

Phase 6: Report generation#180

Open
teresa-ortega wants to merge 10 commits into
next-genfrom
teresa-ortega/report_generation
Open

Phase 6: Report generation#180
teresa-ortega wants to merge 10 commits into
next-genfrom
teresa-ortega/report_generation

Conversation

@teresa-ortega

@teresa-ortega teresa-ortega commented Jun 23, 2026

Copy link
Copy Markdown
Collaborator

Proposed changes

Adds examples/beluga/report.ipynb, a Jupyter cookbook that shows how to explore and visualise APE results from a completed Beluga benchmark run using lambkin.data.access and lambkin.data.evo.

The notebook covers:

  • Explore available data — list variants and iterations using access.iterations().
  • APE timeseries by variant — individual iterations in light color, per-variant mean overlaid in bold.
  • Stats summary table — RMSE mean/std, mean, and max per variant, aggregated across iterations.
  • RMSE comparison — bar chart with error bars across variants.
  • Pandas DataFrame — snippet showing how to convert results to a long-format DataFrame for advanced analysis with seaborn.
  • Export to HTML — how to share the notebook as a standalone HTML file with jupyter nbconvert.

No new SDK modules or dependencies are introduced — the notebook uses only the existing lambkin.data API.

Type of change

  • 🐛 Bugfix (change which fixes an issue)
  • 🚀 Feature (change which adds functionality)
  • 📚 Documentation (change which fixes or extends documentation)

💥 No breaking changes

Checklist

Put an x in the boxes that apply. This is simply a reminder of what we will require before merging your code.

  • Lint and unit tests (if any) pass locally with my changes
  • I have added tests that prove my fix is effective or that my feature works
  • I have added necessary documentation (if appropriate)

Additional comments

N/A

@teresa-ortega
teresa-ortega requested a review from xaru8145 June 23, 2026 16:04
@teresa-ortega teresa-ortega changed the title Phase 6: report generation Phase 6: Report generation Jun 24, 2026
@xaru8145

Copy link
Copy Markdown
Collaborator

Before we go further in the review of this implementation, I want you to think through some scenarios:

  1. What happens when a user wants RPE instead of APE?
  2. What happens when they want both APE and RPE in the same report?
  3. What happens when they only care about RMSE and not the full stats table?

Walk through how a user would achieve each of these with the current report.generate() API. What does that tell you about the generality of this approach?

@teresa-ortega

Copy link
Copy Markdown
Collaborator Author

You're right, the current report.generate() is too opinionated — it hardcodes APE, always generates all three sections, and can't combine multiple metrics in the same report.

I see two ways to fix this:

Option A : composable cells

Instead of a single generate(), the SDK exposes building blocks that the user composes:

import lambkin.data.report as report

nb = report.notebook()
nb.add(report.timeseries("output.ape.zip", title="APE"))
nb.add(report.timeseries("output.rpe.zip", title="RPE"))
nb.add(report.stats_table("output.ape.zip"))
nb.save(output_dir / "report.ipynb")

This handles all three scenarios cleanly. More API surface, but fully flexible.

Option B : generate() with parameters

Keep a single entry point but make it configurable:

report.generate(
    ctx,
    files=["output.ape.zip", "output.rpe.zip"],
    sections=["timeseries", "stats"],
)

Which direction do you prefer?

Signed-off-by: Maria Teresa Ortega <teresa.ortega0903@gmail.com>
Signed-off-by: Maria Teresa Ortega <teresa.ortega0903@gmail.com>
Signed-off-by: Maria Teresa Ortega <teresa.ortega0903@gmail.com>
Signed-off-by: Maria Teresa Ortega <teresa.ortega0903@gmail.com>
Signed-off-by: Maria Teresa Ortega <teresa.ortega0903@gmail.com>
Signed-off-by: Maria Teresa Ortega <teresa.ortega0903@gmail.com>
Signed-off-by: Maria Teresa Ortega <teresa.ortega0903@gmail.com>
@teresa-ortega
teresa-ortega force-pushed the teresa-ortega/report_generation branch from eb5d7ca to 4576a93 Compare June 25, 2026 15:29
Comment thread src/lambkin/README.md Outdated
Comment thread src/lambkin/README.md Outdated
Comment thread examples/beluga/report.ipynb
Signed-off-by: Maria Teresa Ortega <teresa.ortega0903@gmail.com>
Signed-off-by: Maria Teresa Ortega <teresa.ortega0903@gmail.com>
Signed-off-by: Maria Teresa Ortega <teresa.ortega0903@gmail.com>
@teresa-ortega
teresa-ortega requested a review from xaru8145 June 25, 2026 16:15
Comment thread src/lambkin/README.md
Comment on lines +413 to +416
### Analysing results in a notebook

`lambkin.data` functions accept a plain path, so results can be explored
from a Jupyter notebook without re-running the benchmark:

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Framing: The subject should be the notebook as a workflow, not lambkin.data. Something like:

Benchmark results can be explored interactively in a Jupyter notebook after a run. The included report.ipynb provides a starting point; lambkin.data functions accept a plain path so no benchmark context is needed:

Comment thread src/lambkin/README.md
Comment on lines +418 to +447
```python
from collections import defaultdict

import matplotlib.pyplot as plt
import numpy as np
import pandas as pd

from lambkin.data import access, evo as evo_data

RESULTS_DIR = "path/to/results"

# List completed iterations
for entry in access.iterations(RESULTS_DIR):
print(entry.variant, entry.iteration, vars(entry.params))

# Plot APE timeseries per variant
series = evo_data.series(RESULTS_DIR, "output.ape.zip")
for entry in series:
plt.plot(entry.time, entry.error, label=entry.variant, alpha=0.5)
plt.legend()
plt.show()

# Convert to a long-format DataFrame for seaborn
rows = []
for entry in evo_data.stats(RESULTS_DIR, "output.ape.zip"):
row = vars(entry.params).copy()
row.update({"variant": entry.variant, "iteration": entry.iteration,
"rmse": entry.rmse, "mean": entry.mean, "max": entry.max})
rows.append(row)
df = pd.DataFrame(rows)

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The code snippet also reads like a Python script — using print() and plt.show() — which works against the notebook framing. In a notebook, cell outputs render inline; you don't need either.

Rather than writing a new snippet, just point to the Beluga example notebook and note that it can be adapted for different metrics. That's faster and more honest about what the user should actually do.

Comment thread examples/beluga/README.md
jupyter notebook examples/beluga/report.ipynb
```

The notebook plots APE timeseries by variant, prints a stats summary table, and generates an RMSE comparison bar chart. All figures are saved under `results/`.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

in a notebook, outputs render inline, nothing is "printed". Change to "displays" or "shows".

Suggested change
The notebook plots APE timeseries by variant, prints a stats summary table, and generates an RMSE comparison bar chart. All figures are saved under `results/`.
The notebook plots APE timeseries by variant, shows a stats summary table, and generates an RMSE comparison bar chart. All figures are saved under `results/`.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants