Spaces:
Running
Running
| """Render architecture obstacle crossover summary figure for the paper.""" | |
| from __future__ import annotations | |
| import argparse | |
| from pathlib import Path | |
| import matplotlib.pyplot as plt | |
| import pandas as pd | |
| def _parse_args() -> argparse.Namespace: | |
| p = argparse.ArgumentParser(description=__doc__) | |
| p.add_argument( | |
| "--summary-csv", | |
| type=Path, | |
| default=Path("reports") / "architecture_obstacle_crossover" / "crossover_summary.csv", | |
| ) | |
| p.add_argument( | |
| "--out-path", | |
| type=Path, | |
| default=Path("paper") / "figures" / "fig_architecture_obstacle_crossover.png", | |
| ) | |
| return p.parse_args() | |
| def main() -> int: | |
| args = _parse_args() | |
| df = pd.read_csv(args.summary_csv) | |
| if df.empty: | |
| raise SystemExit(f"no rows in {args.summary_csv}") | |
| if "front_empty" not in df.columns: | |
| df["front_empty"] = df["n_points"].eq(0) | |
| fig, ax = plt.subplots(figsize=(7.0, 4.0)) | |
| for scenario_name, group in df.groupby("scenario_name"): | |
| group = group.sort_values("required_obstacle_height_m") | |
| x_cm = group["required_obstacle_height_m"] * 100.0 | |
| y_pct = group["frac_rocker_bogie"] * 100.0 | |
| label = scenario_name.replace("_", " ") | |
| ax.plot(x_cm, y_pct, marker="o", label=label) | |
| empty = group[group["front_empty"].fillna(group["n_points"].eq(0))] | |
| if not empty.empty: | |
| ax.plot( | |
| empty["required_obstacle_height_m"] * 100.0, | |
| [0.0] * len(empty), | |
| linestyle="none", | |
| marker="x", | |
| color=ax.lines[-1].get_color(), | |
| markersize=7, | |
| markeredgewidth=1.5, | |
| ) | |
| ax.set_xlabel("Required obstacle height (cm)") | |
| ax.set_ylabel("Rocker-bogie share of Pareto set (%)") | |
| ax.set_ylim(-2, 102) | |
| ax.grid(True, alpha=0.3) | |
| ax.legend(fontsize=8, loc="best") | |
| fig.tight_layout() | |
| args.out_path.parent.mkdir(parents=True, exist_ok=True) | |
| fig.savefig(args.out_path, dpi=200) | |
| print(f"wrote {args.out_path}") | |
| return 0 | |
| if __name__ == "__main__": | |
| raise SystemExit(main()) | |