1

Réorganisation

This commit is contained in:
2025-11-19 17:01:45 +01:00
parent 566d4400ce
commit 617b12c02e
91 changed files with 874 additions and 1715 deletions

View File

@@ -11,6 +11,7 @@ from .rain import plot_daily_rainfall_hyetograph, plot_rainfall_by_season
from .relationships import (
plot_event_composite,
plot_hexbin_with_third_variable,
plot_pairwise_relationship_grid,
plot_scatter_pair,
)
from .seasonal_profiles import (
@@ -37,6 +38,7 @@ __all__ = [
"plot_rainfall_by_season",
"plot_event_composite",
"plot_hexbin_with_third_variable",
"plot_pairwise_relationship_grid",
"plot_scatter_pair",
"plot_daylight_hours",
"plot_diurnal_cycle",

View File

@@ -21,6 +21,16 @@ def export_plot_dataset(data: Any, output_path: str | Path, *, suffix: str = ".c
output_path = Path(output_path)
dataset_path = output_path.with_suffix(suffix)
# If the image is exported under a "figures" directory, keep the dataset in
# an equivalent "data" directory to avoid mixing assets.
parts = list(dataset_path.parts)
for idx, part in enumerate(parts):
if part == "figures":
parts[idx] = "data"
dataset_path = Path(*parts)
break
dataset_path.parent.mkdir(parents=True, exist_ok=True)
def _normalize(value: Any, *, default_name: str = "value") -> pd.DataFrame:

View File

@@ -13,7 +13,7 @@ import pandas as pd
from .base import export_plot_dataset
from meteo.variables import Variable
__all__ = ['plot_scatter_pair', 'plot_hexbin_with_third_variable', 'plot_event_composite']
__all__ = ['plot_scatter_pair', 'plot_pairwise_relationship_grid', 'plot_hexbin_with_third_variable', 'plot_event_composite']
def plot_scatter_pair(
@@ -193,6 +193,87 @@ def plot_scatter_pair(
return output_path.resolve()
def plot_pairwise_relationship_grid(
df: pd.DataFrame,
variables: Sequence[Variable],
output_path: str | Path,
*,
sample_step: int = 10,
hist_bins: int = 40,
scatter_kwargs: dict | None = None,
) -> Path:
"""Trace un tableau de nuages de points exhaustif (sans doublon)."""
output_path = Path(output_path)
output_path.parent.mkdir(parents=True, exist_ok=True)
if not variables:
raise ValueError("La liste de variables ne peut pas être vide.")
columns = [v.column for v in variables]
for col in columns:
if col not in df.columns:
raise KeyError(f"Colonne absente dans le DataFrame : {col}")
df_pairs = df[columns].dropna()
if df_pairs.empty:
raise RuntimeError("Aucune ligne complète pour générer les nuages de points.")
if sample_step > 1:
df_pairs = df_pairs.iloc[::sample_step, :]
export_plot_dataset(df_pairs, output_path)
n = len(variables)
fig_size = max(3.0, 1.8 * n)
fig, axes = plt.subplots(n, n, figsize=(fig_size, fig_size), squeeze=False)
default_scatter_kwargs = {"s": 5, "alpha": 0.5}
scatter_kwargs = {**default_scatter_kwargs, **(scatter_kwargs or {})}
for row_idx, var_y in enumerate(variables):
for col_idx, var_x in enumerate(variables):
ax = axes[row_idx][col_idx]
if row_idx < col_idx:
# Triangle supérieur vide pour éviter les doublons
ax.set_visible(False)
continue
if row_idx == col_idx:
series = df_pairs[var_x.column].dropna()
if series.empty:
ax.text(0.5, 0.5, "(vide)", ha="center", va="center")
ax.set_axis_off()
else:
bins = min(hist_bins, max(5, series.nunique()))
ax.hist(series, bins=bins, color="tab:blue", alpha=0.7)
ax.set_ylabel("")
else:
ax.scatter(
df_pairs[var_x.column],
df_pairs[var_y.column],
**scatter_kwargs,
)
if row_idx == n - 1:
ax.set_xlabel(var_x.label)
else:
ax.set_xticklabels([])
if col_idx == 0:
ax.set_ylabel(var_y.label)
else:
ax.set_yticklabels([])
fig.suptitle("Matrice de corrélations simples (nuages de points)")
fig.tight_layout(rect=[0, 0, 1, 0.97])
fig.savefig(output_path, dpi=150)
plt.close(fig)
return output_path.resolve()
def plot_hexbin_with_third_variable(
df: pd.DataFrame,
var_x: Variable,