# scripts/run_all_plots.py from __future__ import annotations import argparse import subprocess import sys from dataclasses import dataclass from pathlib import Path from typing import Iterable PROJECT_ROOT = Path(__file__).resolve().parents[1] @dataclass(frozen=True) class PlotScript: key: str path: Path def display_path(self) -> str: try: return str(self.path.relative_to(PROJECT_ROOT)) except ValueError: return str(self.path) PLOT_SCRIPTS: tuple[PlotScript, ...] = ( PlotScript( "plot_basic_variables", PROJECT_ROOT / "docs" / "03 - Premiers graphiques" / "scripts" / "plot_basic_variables.py", ), PlotScript("plot_calendar_overview", PROJECT_ROOT / "scripts" / "plot_calendar_overview.py"), PlotScript( "plot_all_pairwise_scatter", PROJECT_ROOT / "docs" / "04 - Corrélations binaires" / "scripts" / "plot_all_pairwise_scatter.py", ), PlotScript( "plot_correlation_heatmap", PROJECT_ROOT / "docs" / "04 - Corrélations binaires" / "scripts" / "plot_correlation_heatmap.py", ), PlotScript("plot_diurnal_cycle", PROJECT_ROOT / "scripts" / "plot_diurnal_cycle.py"), PlotScript("plot_illuminance_focus", PROJECT_ROOT / "scripts" / "plot_illuminance_focus.py"), PlotScript( "plot_hexbin_explorations", PROJECT_ROOT / "docs" / "06 - Corrélations multiples" / "scripts" / "plot_hexbin_explorations.py", ), PlotScript("plot_monthly_patterns", PROJECT_ROOT / "scripts" / "plot_monthly_patterns.py"), PlotScript("plot_rain_event_composites", PROJECT_ROOT / "scripts" / "plot_rain_event_composites.py"), PlotScript("plot_rain_hyetograph", PROJECT_ROOT / "scripts" / "plot_rain_hyetograph.py"), PlotScript( "plot_lagged_correlations", PROJECT_ROOT / "docs" / "05 - Corrélations binaires avancées" / "scripts" / "plot_lagged_correlations.py", ), PlotScript( "plot_rolling_correlation_heatmap", PROJECT_ROOT / "docs" / "05 - Corrélations binaires avancées" / "scripts" / "plot_rolling_correlation_heatmap.py", ), PlotScript("plot_seasonal_overview", PROJECT_ROOT / "scripts" / "plot_seasonal_overview.py"), PlotScript( "plot_sun_elevation_relationships", PROJECT_ROOT / "scripts" / "plot_sun_elevation_relationships.py", ), PlotScript("plot_wind_conditionals", PROJECT_ROOT / "scripts" / "plot_wind_conditionals.py"), PlotScript("plot_wind_rose", PROJECT_ROOT / "scripts" / "plot_wind_rose.py"), PlotScript("plot_wind_rose_rain", PROJECT_ROOT / "scripts" / "plot_wind_rose_rain.py"), ) def _normalize_key(name: str) -> str: normalized = name.strip() if not normalized: raise ValueError("Nom de script vide.") if normalized.startswith("scripts."): normalized = normalized.split(".", 1)[1] return normalized def iter_scripts(selected: Iterable[str] | None) -> list[PlotScript]: if not selected: return list(PLOT_SCRIPTS) mapping = {script.key: script for script in PLOT_SCRIPTS} normalized = [_normalize_key(name) for name in selected] scripts: list[PlotScript] = [] missing: list[str] = [] for key in normalized: script = mapping.get(key) if script is None: missing.append(key) else: scripts.append(script) if missing: available = "\n - ".join(("",) + tuple(script.key for script in PLOT_SCRIPTS)) missing_list = "\n - ".join(("",) + tuple(missing)) raise SystemExit( "\n".join( [ "Les scripts suivants ne sont pas reconnus :", missing_list, "", "Scripts disponibles :", available, ] ) ) return scripts def run_script(script: PlotScript) -> bool: if not script.path.exists(): print(f"✘ Script introuvable : {script.display_path()}") return False cmd = [sys.executable, str(script.path)] print(f"\n=== {script.key} ({script.display_path()}) ===") result = subprocess.run(cmd, check=False) if result.returncode == 0: print(f"✔ {script.key} terminé avec succès.") return True print(f"✘ {script.key} a échoué (code {result.returncode}).") return False def main(argv: list[str] | None = None) -> int: parser = argparse.ArgumentParser(description="Lance tous les scripts de tracé météorologiques.") parser.add_argument( "--only", nargs="*", help="Limiter l'exécution à certains scripts (ex: plot_temperature).", ) args = parser.parse_args(argv) scripts = iter_scripts(args.only) print(f"Exécution de {len(scripts)} script(s) de tracé…") success_count = 0 for script in scripts: if run_script(script): success_count += 1 print() print(f"Scripts réussis : {success_count}/{len(scripts)}") failed = len(scripts) - success_count if failed: print(f"⚠ {failed} script(s) ont échoué. Consultez les messages ci-dessus.") return 1 print("✔ Tous les scripts ont été exécutés avec succès.") return 0 if __name__ == "__main__": # pragma: no cover raise SystemExit(main())