"""Tracés orientés calendrier (heatmaps quotidiennes et profils hebdomadaires).""" from __future__ import annotations from pathlib import Path from typing import Sequence import matplotlib.pyplot as plt import numpy as np import pandas as pd from .base import export_plot_dataset from meteo.variables import Variable __all__ = ['plot_calendar_heatmap', 'plot_weekday_profiles'] def plot_calendar_heatmap( matrix: pd.DataFrame, output_path: str | Path, *, title: str, cmap: str = "YlGnBu", colorbar_label: str = "", ) -> Path: """ Affiche une heatmap calendrier (lignes = mois, colonnes = jours). """ output_path = Path(output_path) output_path.parent.mkdir(parents=True, exist_ok=True) export_plot_dataset(matrix, output_path) if matrix.empty: fig, ax = plt.subplots() ax.text(0.5, 0.5, "Pas de données pour la heatmap.", ha="center", va="center") ax.set_axis_off() fig.savefig(output_path, dpi=150, bbox_inches="tight") plt.close(fig) return output_path.resolve() fig, ax = plt.subplots(figsize=(14, 6)) data = matrix.to_numpy(dtype=float) im = ax.imshow(data, aspect="auto", cmap=cmap, interpolation="nearest") ax.set_xticks(np.arange(matrix.shape[1])) ax.set_xticklabels(matrix.columns, rotation=90) ax.set_yticks(np.arange(matrix.shape[0])) ax.set_yticklabels(matrix.index) ax.set_xlabel("Jour du mois") ax.set_ylabel("Mois") ax.set_title(title) cbar = fig.colorbar(im, ax=ax) if colorbar_label: cbar.set_label(colorbar_label) fig.tight_layout() fig.savefig(output_path, dpi=150) plt.close(fig) return output_path.resolve() def plot_weekday_profiles( weekday_df: pd.DataFrame, variables: Sequence[Variable], output_path: str | Path, *, title: str, ) -> Path: """ Affiche les moyennes par jour de semaine pour plusieurs variables. """ output_path = Path(output_path) output_path.parent.mkdir(parents=True, exist_ok=True) if weekday_df.empty: fig, ax = plt.subplots() ax.text(0.5, 0.5, "Pas de données hebdomadaires.", ha="center", va="center") ax.set_axis_off() fig.savefig(output_path, dpi=150, bbox_inches="tight") plt.close(fig) return output_path.resolve() export_plot_dataset(weekday_df, output_path) weekday_labels = ["Lun", "Mar", "Mer", "Jeu", "Ven", "Sam", "Dim"] n_vars = len(variables) fig, axes = plt.subplots(n_vars, 1, figsize=(10, 3 * n_vars), sharex=True) if n_vars == 1: axes = [axes] x = np.arange(len(weekday_labels)) for ax, var in zip(axes, variables): if var.column not in weekday_df.columns: ax.text(0.5, 0.5, f"Aucune donnée pour {var.label}.", ha="center", va="center") ax.set_axis_off() continue values = weekday_df[var.column].to_numpy(dtype=float) ax.plot(x, values, marker="o", label=var.label) ax.set_ylabel(f"{var.label} ({var.unit})" if var.unit else var.label) ax.grid(True, linestyle=":", alpha=0.5) ax.set_xticks(x) ax.set_xticklabels(weekday_labels) axes[-1].set_xlabel("Jour de semaine") axes[0].legend(loc="upper right") fig.suptitle(title) fig.tight_layout(rect=[0, 0, 1, 0.97]) fig.savefig(output_path, dpi=150) plt.close(fig) return output_path.resolve()