1

Corrélations multiples

This commit is contained in:
2025-11-25 15:40:49 +01:00
parent 1932938fd6
commit 18afeb1e8b
10 changed files with 211 additions and 36 deletions

View File

@@ -111,6 +111,19 @@ DEFAULT_HEXBIN_SCENARIOS: Sequence[HexbinScenario] = (
gridsize=50,
mincnt=8,
),
HexbinScenario(
key_x="sun_elevation",
key_y="temperature",
key_color="humidity",
filename="hexbin_sunelev_temp_color_humidity.png",
description=(
"Suivre le cycle diurne : la température grimpe avec l'élévation solaire "
"et l'humidité médiane chute nettement une fois le soleil levé."
),
reduce="median",
gridsize=60,
mincnt=8,
),
HexbinScenario(
key_x="pressure",
key_y="rain_rate",
@@ -137,6 +150,20 @@ DEFAULT_HEXBIN_SCENARIOS: Sequence[HexbinScenario] = (
gridsize=55,
mincnt=6,
),
HexbinScenario(
key_x="sun_elevation",
key_y="illuminance",
key_color="rain_rate",
filename="hexbin_sunelev_lux_color_rain.png",
description=(
"Comparer l'ensoleillement théorique (élévation solaire) et la luminance mesurée, "
"et repérer les épisodes où la pluie ou un ciel très couvert écrasent la lumière "
"malgré un soleil haut."
),
reduce="max",
gridsize=48,
mincnt=3,
),
)

View File

@@ -24,6 +24,12 @@ from .relationships import (
plot_pairwise_relationship_grid,
plot_scatter_pair,
)
from .hexbin import (
HexbinPlotResult,
generate_hexbin_for_scenario,
generate_hexbin_scenarios,
prepare_hexbin_dataframe,
)
from .basic_series import (
PlotChoice,
PlotStyle,
@@ -66,6 +72,10 @@ __all__ = [
"plot_hexbin_with_third_variable",
"plot_pairwise_relationship_grid",
"plot_scatter_pair",
"HexbinPlotResult",
"generate_hexbin_for_scenario",
"generate_hexbin_scenarios",
"prepare_hexbin_dataframe",
"PlotChoice",
"PlotStyle",
"plot_basic_series",

127
meteo/plots/hexbin.py Normal file
View File

@@ -0,0 +1,127 @@
"""Fonctions utilitaires pour générer des hexbins à partir de scénarios."""
from __future__ import annotations
from dataclasses import dataclass
from pathlib import Path
from typing import Sequence
import pandas as pd
from meteo.correlation_presets import HexbinScenario
from meteo.variables import VARIABLES_BY_KEY, Variable
from .relationships import plot_hexbin_with_third_variable
__all__ = [
"HexbinPlotResult",
"prepare_hexbin_dataframe",
"generate_hexbin_for_scenario",
"generate_hexbin_scenarios",
]
@dataclass(frozen=True)
class HexbinPlotResult:
"""Résultat d'un hexbin généré à partir d'un scénario prédéfini."""
scenario: HexbinScenario
var_x: Variable
var_y: Variable
var_color: Variable
output_path: Path
point_count: int
def _get_variables_for_scenario(scenario: HexbinScenario) -> tuple[Variable, Variable, Variable]:
try:
return (
VARIABLES_BY_KEY[scenario.key_x],
VARIABLES_BY_KEY[scenario.key_y],
VARIABLES_BY_KEY[scenario.key_color],
)
except KeyError as exc:
raise KeyError(f"Variable inconnue dans le scénario hexbin : {exc}") from exc
def prepare_hexbin_dataframe(
df: pd.DataFrame,
var_x: Variable,
var_y: Variable,
var_color: Variable,
) -> pd.DataFrame:
"""Sélectionne et nettoie les colonnes utiles à un hexbin."""
columns = [var_x.column, var_y.column, var_color.column]
missing = [col for col in columns if col not in df.columns]
if missing:
raise KeyError(f"Colonnes absentes dans le DataFrame : {missing}")
return df[columns].dropna()
def generate_hexbin_for_scenario(
df: pd.DataFrame,
scenario: HexbinScenario,
*,
base_output_dir: str | Path,
cmap: str = "viridis",
) -> HexbinPlotResult:
"""Construit un hexbin complet à partir d'un scénario et retourne ses métadonnées."""
var_x, var_y, var_color = _get_variables_for_scenario(scenario)
cleaned_df = prepare_hexbin_dataframe(df, var_x, var_y, var_color)
output_dir = Path(base_output_dir)
output_dir.mkdir(parents=True, exist_ok=True)
output_path = output_dir / scenario.filename
reduce_func = scenario.get_reduce_func()
reduce_label = scenario.get_reduce_label()
plot_hexbin_with_third_variable(
df=cleaned_df,
var_x=var_x,
var_y=var_y,
var_color=var_color,
output_path=output_path,
gridsize=scenario.gridsize,
mincnt=scenario.mincnt,
reduce_func=reduce_func,
reduce_func_label=reduce_label,
cmap=cmap,
)
return HexbinPlotResult(
scenario=scenario,
var_x=var_x,
var_y=var_y,
var_color=var_color,
output_path=output_path.resolve(),
point_count=len(cleaned_df),
)
def generate_hexbin_scenarios(
df: pd.DataFrame,
scenarios: Sequence[HexbinScenario],
*,
base_output_dir: str | Path,
cmap: str = "viridis",
) -> list[HexbinPlotResult]:
"""Génère en série plusieurs hexbins prédéfinis et retourne les résultats."""
if not scenarios:
raise ValueError("Aucun scénario hexbin fourni.")
results: list[HexbinPlotResult] = []
for scenario in scenarios:
result = generate_hexbin_for_scenario(
df=df,
scenario=scenario,
base_output_dir=base_output_dir,
cmap=cmap,
)
results.append(result)
return results