| """Master entry point: generate the whole figures_paper set. |
| |
| Usage: |
| python figures_paper/scripts/make_all_figures.py --package-root . |
| |
| Behaviour: |
| * auto-creates figures_paper/{pdf,png,svg,data}; |
| * each figure is isolated in try/except so one failure never aborts the rest; |
| * reads real CSV/NPY files where present, otherwise uses reported fallback numbers; |
| * prints a per-figure status table; |
| * writes figures_paper/README_figures.md with captions, sources, file paths and notes. |
| """ |
| from __future__ import annotations |
| import argparse |
| import importlib.util |
| import sys |
| import traceback |
| from pathlib import Path |
|
|
| import style |
|
|
| |
| FIGURES = [ |
| ("fig1_graph_overview.py", "Sec. Introduction / Task definition"), |
| ("fig2_sparsity.py", "Sec. Dataset"), |
| ("fig3_roadmap.py", "Sec. Results (overview)"), |
| ("fig4_architecture.py", "Sec. Method"), |
| ("fig5_ablation_highorder.py", "Sec. Ablation"), |
| ("fig6_rank_vs_threshold.py", "Sec. Method / Decision rule"), |
| ("fig7_error_heatmap.py", "Sec. Error analysis"), |
| ("figA1_hyperparam.py", "Appendix"), |
| ("figA2_rw_ablation.py", "Appendix"), |
| ("figA3_feature_importance.py", "Appendix"), |
| ("figA4_oof_pr.py", "Appendix"), |
| ] |
|
|
|
|
| def _load(fname, scripts): |
| spec = importlib.util.spec_from_file_location(fname[:-3], scripts / fname) |
| mod = importlib.util.module_from_spec(spec) |
| spec.loader.exec_module(mod) |
| return mod |
|
|
|
|
| def main(): |
| ap = argparse.ArgumentParser() |
| ap.add_argument("--package-root", default=".", help="repo root containing data_and_docs/ and validation_runs/") |
| args = ap.parse_args() |
| root = Path(args.package_root).resolve() |
| scripts = Path(__file__).resolve().parent |
| out = style.ensure_dirs(root) |
|
|
| results = [] |
| for fname, latex in FIGURES: |
| try: |
| mod = _load(fname, scripts) |
| res = mod.make(root, out) |
| except Exception as e: |
| res = dict(key=fname[:-3], title=fname, status="error", files=[], sources=[], |
| caption="", note=f"{type(e).__name__}: {e}", traceback=traceback.format_exc()) |
| res["latex"] = latex |
| results.append(res) |
| print(f"[{res.get('status','?'):>8}] {res['key']}") |
|
|
| _write_readme(root, results) |
| print("\n=== summary ===") |
| for r in results: |
| print(f" {r['key']:<28} {r.get('status','?'):<8} -> {', '.join(r.get('files', [])) or '(no files)'}") |
| print("\nREADME -> figures_paper/README_figures.md") |
|
|
|
|
| def _write_readme(root, results): |
| lines = [ |
| "# Figures for the CS3319 Project 2 paper\n", |
| "Auto-generated by `figures_paper/scripts/make_all_figures.py`. Every figure is emitted as " |
| "`.pdf` (vector, `pdf.fonttype=42` TrueType-embedded — venue-safe), `.png` (300 dpi preview) " |
| "and `.svg`. Widths follow ACM `sigconf`: single-column 3.25 in, double-column 6.75 in.\n", |
| "## Generation\n", |
| "```bash\npython figures_paper/scripts/make_all_figures.py --package-root .\n```\n", |
| "## Status\n", |
| "| figure | status | files | suggested placement |\n|---|---|---|---|", |
| ] |
| for r in results: |
| status = r.get("status", "?") |
| files = ", ".join(r.get("files", [])) or "—" |
| lines.append(f"| {r['key']} | {status} | {files} | {r.get('latex','')} |") |
| lines.append("\n## Captions, sources and notes\n") |
| for r in results: |
| lines.append(f"### {r['title']}") |
| lines.append(f"- **status:** {r.get('status','?')}") |
| if r.get("sources"): |
| lines.append("- **data sources:** " + "; ".join(r["sources"])) |
| if r.get("files"): |
| lines.append("- **files:** " + ", ".join( |
| f"`figures_paper/{{pdf,png,svg}}/{f}`" for f in r["files"])) |
| cap = r.get("caption", "").strip() |
| if cap: |
| lines.append(f"- **caption draft:** {cap}") |
| if r.get("note"): |
| lines.append(f"- **note:** {r['note']}") |
| if r.get("traceback"): |
| lines.append("```python\n" + r["traceback"] + "\n```") |
| lines.append("") |
|
|
| lines += [ |
| "## Inserting into LaTeX (ACM sigconf)\n", |
| "```latex\n\\usepackage{graphicx}\n", |
| "% single-column (3.25 in)\n\\begin{figure}\n \\centering\n \\includegraphics[width=\\columnwidth]{figures_paper/pdf/fig2_sparsity.pdf}\n \\caption{...}\n\\end{figure}\n", |
| "% double-column (6.75 in)\n\\begin{figure*}\n \\centering\n \\includegraphics[width=\\textwidth]{figures_paper/pdf/fig3_roadmap.pdf}\n \\caption{...}\n\\end{figure*}\n```\n", |
| "Use the `.pdf` for the camera-ready (vector, embedded fonts); the `.png` is only for " |
| "previews / draft review.\n", |
| ] |
| (root / "figures_paper" / "README_figures.md").write_text("\n".join(lines), encoding="utf-8") |
|
|
|
|
| if __name__ == "__main__": |
| |
| sys.path.insert(0, str(Path(__file__).resolve().parent)) |
| main() |
|
|