You've already forked donnees_meteo
Réorganisation
This commit is contained in:
@@ -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",
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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,
|
||||
|
||||
Reference in New Issue
Block a user