Compare commits
No commits in common. "3a1f7e2a7e45374352615c2a8f01f65577779c1c" and "79603b7c3e664cdd8aaa5a8e6eafd55e801a6e81" have entirely different histories.
3a1f7e2a7e
...
79603b7c3e
Binary file not shown.
|
Before Width: | Height: | Size: 46 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 55 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 49 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 45 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 46 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 45 KiB |
@ -4,18 +4,16 @@ On peut désormais tracer nos premiers graphiques simples et bruts.
|
|||||||
S'ils ne sont pas très instructifs par rapport à ce que nous fournissent Home Assistant et InfluxDB, ils nous permettent au moins de nous assurer que tout fonctionne, et que les données semblent cohérentes.
|
S'ils ne sont pas très instructifs par rapport à ce que nous fournissent Home Assistant et InfluxDB, ils nous permettent au moins de nous assurer que tout fonctionne, et que les données semblent cohérentes.
|
||||||
Les fichiers CSV correspondant à chaque figure sont conservés dans `data/` dans ce dossier.
|
Les fichiers CSV correspondant à chaque figure sont conservés dans `data/` dans ce dossier.
|
||||||
|
|
||||||
On se limite dans un premier temps aux 7 derniers jours.
|
|
||||||
|
|
||||||
```shell
|
```shell
|
||||||
python "docs/03 - Premiers graphiques/scripts/plot_basic_variables.py"
|
python "docs/03 - Premiers graphiques/scripts/plot_basic_variables.py"
|
||||||
```
|
```
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||

|
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
|

|
||||||
|
|
||||||

|

|
||||||
|
|
||||||

|

|
||||||
@ -25,26 +23,3 @@ python "docs/03 - Premiers graphiques/scripts/plot_basic_variables.py"
|
|||||||

|

|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
## Vues calendrier
|
|
||||||
|
|
||||||
Les vues calendrier permettent de visualiser, jour par jour, les cumuls ou moyennes quotidiennes sur la dernière année complète disponible.
|
|
||||||
Les images générées sont stockées dans `figures/calendar/` et les CSV correspondants dans `data/calendar/`.
|
|
||||||
|
|
||||||
```shell
|
|
||||||
python "docs/03 - Premiers graphiques/scripts/plot_calendar_overview.py"
|
|
||||||
```
|
|
||||||
|
|
||||||

|
|
||||||
|
|
||||||

|
|
||||||
|
|
||||||

|
|
||||||
|
|
||||||

|
|
||||||
|
|
||||||

|
|
||||||
|
|
||||||

|
|
||||||
|
|
||||||
Ces vues, bien que simples en principe, mettent déjà mieux en évidence les fluctuations au cours du temps.
|
|
||||||
|
|||||||
@ -1,121 +0,0 @@
|
|||||||
# docs/03 - Premiers graphiques/scripts/plot_calendar_overview.py
|
|
||||||
from __future__ import annotations
|
|
||||||
|
|
||||||
from pathlib import Path
|
|
||||||
import sys
|
|
||||||
|
|
||||||
import pandas as pd
|
|
||||||
|
|
||||||
PROJECT_ROOT = Path(__file__).resolve().parents[3]
|
|
||||||
if str(PROJECT_ROOT) not in sys.path:
|
|
||||||
sys.path.insert(0, str(PROJECT_ROOT))
|
|
||||||
|
|
||||||
from meteo.dataset import load_raw_csv
|
|
||||||
from meteo.plots import (
|
|
||||||
CalendarHeatmapSpec,
|
|
||||||
daily_mean_series,
|
|
||||||
generate_calendar_heatmaps,
|
|
||||||
rainfall_daily_total_series,
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
DOC_DIR = Path(__file__).resolve().parent.parent
|
|
||||||
CSV_PATH = PROJECT_ROOT / "data" / "weather_minutely.csv"
|
|
||||||
OUTPUT_DIR = DOC_DIR / "figures" / "calendar"
|
|
||||||
|
|
||||||
HEATMAP_SPECS: tuple[CalendarHeatmapSpec, ...] = (
|
|
||||||
CalendarHeatmapSpec(
|
|
||||||
key="rain",
|
|
||||||
agg_label="Pluie (mm)",
|
|
||||||
title_template="Pluie quotidienne - {year}",
|
|
||||||
cmap="Blues",
|
|
||||||
colorbar_label="mm",
|
|
||||||
aggregator=rainfall_daily_total_series,
|
|
||||||
),
|
|
||||||
CalendarHeatmapSpec(
|
|
||||||
key="temperature",
|
|
||||||
agg_label="Température (°C)",
|
|
||||||
title_template="Température moyenne quotidienne - {year}",
|
|
||||||
cmap="coolwarm",
|
|
||||||
colorbar_label="°C",
|
|
||||||
aggregator=daily_mean_series("temperature"),
|
|
||||||
),
|
|
||||||
CalendarHeatmapSpec(
|
|
||||||
key="humidity",
|
|
||||||
agg_label="Humidité relative (%)",
|
|
||||||
title_template="Humidité relative quotidienne - {year}",
|
|
||||||
cmap="PuBu",
|
|
||||||
colorbar_label="%",
|
|
||||||
aggregator=daily_mean_series("humidity"),
|
|
||||||
),
|
|
||||||
CalendarHeatmapSpec(
|
|
||||||
key="pressure",
|
|
||||||
agg_label="Pression (hPa)",
|
|
||||||
title_template="Pression moyenne quotidienne - {year}",
|
|
||||||
cmap="Greens",
|
|
||||||
colorbar_label="hPa",
|
|
||||||
aggregator=daily_mean_series("pressure"),
|
|
||||||
),
|
|
||||||
CalendarHeatmapSpec(
|
|
||||||
key="illuminance",
|
|
||||||
agg_label="Illuminance (lux)",
|
|
||||||
title_template="Illuminance moyenne quotidienne - {year}",
|
|
||||||
cmap="YlOrBr",
|
|
||||||
colorbar_label="lux",
|
|
||||||
aggregator=daily_mean_series("illuminance"),
|
|
||||||
),
|
|
||||||
CalendarHeatmapSpec(
|
|
||||||
key="wind",
|
|
||||||
agg_label="Vent (km/h)",
|
|
||||||
title_template="Vitesse moyenne du vent - {year}",
|
|
||||||
cmap="Purples",
|
|
||||||
colorbar_label="km/h",
|
|
||||||
aggregator=daily_mean_series("wind_speed"),
|
|
||||||
),
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
def main() -> None:
|
|
||||||
if not CSV_PATH.exists():
|
|
||||||
print(f"⚠ Fichier introuvable : {CSV_PATH}")
|
|
||||||
return
|
|
||||||
|
|
||||||
df = load_raw_csv(CSV_PATH)
|
|
||||||
if df.empty:
|
|
||||||
print("⚠ Dataset vide.")
|
|
||||||
return
|
|
||||||
|
|
||||||
if not isinstance(df.index, pd.DatetimeIndex):
|
|
||||||
print("⚠ Le dataset doit avoir un index temporel.")
|
|
||||||
return
|
|
||||||
|
|
||||||
print(f"Dataset minuté chargé : {CSV_PATH}")
|
|
||||||
print(f" Lignes : {len(df)}")
|
|
||||||
print(f" Colonnes : {list(df.columns)}")
|
|
||||||
print()
|
|
||||||
|
|
||||||
OUTPUT_DIR.mkdir(parents=True, exist_ok=True)
|
|
||||||
|
|
||||||
latest_year = df.index.year.max()
|
|
||||||
print(f"Année retenue pour le calendrier : {latest_year}")
|
|
||||||
|
|
||||||
results = generate_calendar_heatmaps(
|
|
||||||
df=df,
|
|
||||||
specs=HEATMAP_SPECS,
|
|
||||||
year=latest_year,
|
|
||||||
output_dir=OUTPUT_DIR,
|
|
||||||
)
|
|
||||||
|
|
||||||
for result in results:
|
|
||||||
title = result.spec.title_template.format(year=latest_year)
|
|
||||||
if result.output_path:
|
|
||||||
print(f"✔ {title} : {result.output_path}")
|
|
||||||
else:
|
|
||||||
reason = f" ({result.reason})" if result.reason else ""
|
|
||||||
print(f"⚠ Heatmap ignorée pour {result.spec.key}{reason}.")
|
|
||||||
|
|
||||||
print("✔ Graphiques calendrier générés.")
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
main()
|
|
||||||
@ -2,14 +2,6 @@ from __future__ import annotations
|
|||||||
|
|
||||||
from .base import export_plot_dataset
|
from .base import export_plot_dataset
|
||||||
from .calendar import plot_calendar_heatmap, plot_weekday_profiles
|
from .calendar import plot_calendar_heatmap, plot_weekday_profiles
|
||||||
from .calendar_overview import (
|
|
||||||
CalendarHeatmapResult,
|
|
||||||
CalendarHeatmapSpec,
|
|
||||||
daily_mean_series,
|
|
||||||
format_calendar_matrix,
|
|
||||||
generate_calendar_heatmaps,
|
|
||||||
rainfall_daily_total_series,
|
|
||||||
)
|
|
||||||
from .correlations import (
|
from .correlations import (
|
||||||
plot_correlation_heatmap,
|
plot_correlation_heatmap,
|
||||||
plot_lagged_correlation,
|
plot_lagged_correlation,
|
||||||
@ -39,12 +31,6 @@ __all__ = [
|
|||||||
"export_plot_dataset",
|
"export_plot_dataset",
|
||||||
"plot_calendar_heatmap",
|
"plot_calendar_heatmap",
|
||||||
"plot_weekday_profiles",
|
"plot_weekday_profiles",
|
||||||
"CalendarHeatmapResult",
|
|
||||||
"CalendarHeatmapSpec",
|
|
||||||
"daily_mean_series",
|
|
||||||
"format_calendar_matrix",
|
|
||||||
"generate_calendar_heatmaps",
|
|
||||||
"rainfall_daily_total_series",
|
|
||||||
"plot_correlation_heatmap",
|
"plot_correlation_heatmap",
|
||||||
"plot_lagged_correlation",
|
"plot_lagged_correlation",
|
||||||
"plot_rolling_correlation_heatmap",
|
"plot_rolling_correlation_heatmap",
|
||||||
|
|||||||
@ -1,152 +0,0 @@
|
|||||||
"""Utilitaires pour générer des heatmaps calendrier configurables."""
|
|
||||||
|
|
||||||
from __future__ import annotations
|
|
||||||
|
|
||||||
import calendar
|
|
||||||
from dataclasses import dataclass
|
|
||||||
from pathlib import Path
|
|
||||||
from typing import Callable, Sequence
|
|
||||||
|
|
||||||
import numpy as np
|
|
||||||
import pandas as pd
|
|
||||||
|
|
||||||
from meteo.analysis import compute_daily_rainfall_totals
|
|
||||||
|
|
||||||
from .calendar import plot_calendar_heatmap
|
|
||||||
|
|
||||||
CalendarAggregator = Callable[[pd.DataFrame], pd.Series]
|
|
||||||
|
|
||||||
__all__ = [
|
|
||||||
"CalendarHeatmapSpec",
|
|
||||||
"CalendarHeatmapResult",
|
|
||||||
"daily_mean_series",
|
|
||||||
"rainfall_daily_total_series",
|
|
||||||
"format_calendar_matrix",
|
|
||||||
"generate_calendar_heatmaps",
|
|
||||||
]
|
|
||||||
|
|
||||||
|
|
||||||
@dataclass(frozen=True)
|
|
||||||
class CalendarHeatmapSpec:
|
|
||||||
"""Description d'une heatmap calendrier à générer."""
|
|
||||||
|
|
||||||
key: str
|
|
||||||
agg_label: str
|
|
||||||
title_template: str
|
|
||||||
cmap: str
|
|
||||||
colorbar_label: str
|
|
||||||
aggregator: CalendarAggregator
|
|
||||||
|
|
||||||
|
|
||||||
@dataclass(frozen=True)
|
|
||||||
class CalendarHeatmapResult:
|
|
||||||
"""Résultat d'une tentative de génération de heatmap calendrier."""
|
|
||||||
|
|
||||||
spec: CalendarHeatmapSpec
|
|
||||||
output_path: Path | None
|
|
||||||
reason: str | None = None
|
|
||||||
|
|
||||||
|
|
||||||
def daily_mean_series(column: str) -> CalendarAggregator:
|
|
||||||
"""Retourne un agrégateur qui calcule la moyenne quotidienne d'une colonne."""
|
|
||||||
|
|
||||||
def _aggregator(df: pd.DataFrame) -> pd.Series:
|
|
||||||
if column not in df.columns:
|
|
||||||
raise KeyError(column)
|
|
||||||
if not isinstance(df.index, pd.DatetimeIndex):
|
|
||||||
raise TypeError("Le DataFrame doit être indexé par des timestamps pour les moyennes quotidiennes.")
|
|
||||||
return df[column].resample("1D").mean()
|
|
||||||
|
|
||||||
return _aggregator
|
|
||||||
|
|
||||||
|
|
||||||
def rainfall_daily_total_series(df: pd.DataFrame) -> pd.Series:
|
|
||||||
"""Calcule les cumuls quotidiens de précipitations."""
|
|
||||||
|
|
||||||
totals = compute_daily_rainfall_totals(df=df)
|
|
||||||
return totals["daily_total"]
|
|
||||||
|
|
||||||
|
|
||||||
def format_calendar_matrix(series: pd.Series, year: int, agg_label: str) -> pd.DataFrame:
|
|
||||||
"""Transforme une série quotidienne en matrice calendrier mois x jours."""
|
|
||||||
|
|
||||||
if not isinstance(series.index, pd.DatetimeIndex):
|
|
||||||
raise TypeError("La série doit avoir un index temporel pour être convertie en calendrier.")
|
|
||||||
|
|
||||||
tz = series.index.tz
|
|
||||||
start = pd.Timestamp(year=year, month=1, day=1, tz=tz)
|
|
||||||
end = pd.Timestamp(year=year, month=12, day=31, tz=tz)
|
|
||||||
filtered = series.loc[(series.index >= start) & (series.index <= end)]
|
|
||||||
|
|
||||||
matrix = pd.DataFrame(
|
|
||||||
np.nan,
|
|
||||||
index=[calendar.month_name[m][:3] for m in range(1, 13)],
|
|
||||||
columns=list(range(1, 32)),
|
|
||||||
)
|
|
||||||
|
|
||||||
for timestamp, value in filtered.items():
|
|
||||||
matrix.at[calendar.month_name[timestamp.month][:3], timestamp.day] = value
|
|
||||||
|
|
||||||
matrix.index.name = f"{agg_label} ({year})"
|
|
||||||
return matrix
|
|
||||||
|
|
||||||
|
|
||||||
def generate_calendar_heatmaps(
|
|
||||||
df: pd.DataFrame,
|
|
||||||
specs: Sequence[CalendarHeatmapSpec],
|
|
||||||
*,
|
|
||||||
year: int,
|
|
||||||
output_dir: str | Path,
|
|
||||||
) -> list[CalendarHeatmapResult]:
|
|
||||||
"""Génère l'ensemble des heatmaps calendrier décrites dans `specs`."""
|
|
||||||
|
|
||||||
output_dir = Path(output_dir)
|
|
||||||
output_dir.mkdir(parents=True, exist_ok=True)
|
|
||||||
|
|
||||||
results: list[CalendarHeatmapResult] = []
|
|
||||||
for spec in specs:
|
|
||||||
try:
|
|
||||||
daily_series = spec.aggregator(df)
|
|
||||||
except Exception as exc:
|
|
||||||
results.append(
|
|
||||||
CalendarHeatmapResult(
|
|
||||||
spec=spec,
|
|
||||||
output_path=None,
|
|
||||||
reason=str(exc),
|
|
||||||
)
|
|
||||||
)
|
|
||||||
continue
|
|
||||||
|
|
||||||
if daily_series is None or daily_series.empty:
|
|
||||||
results.append(
|
|
||||||
CalendarHeatmapResult(
|
|
||||||
spec=spec,
|
|
||||||
output_path=None,
|
|
||||||
reason="Série vide ou invalide.",
|
|
||||||
)
|
|
||||||
)
|
|
||||||
continue
|
|
||||||
|
|
||||||
try:
|
|
||||||
matrix = format_calendar_matrix(daily_series, year, spec.agg_label)
|
|
||||||
except Exception as exc: # pragma: no cover - remonté au résultat
|
|
||||||
results.append(
|
|
||||||
CalendarHeatmapResult(
|
|
||||||
spec=spec,
|
|
||||||
output_path=None,
|
|
||||||
reason=str(exc),
|
|
||||||
)
|
|
||||||
)
|
|
||||||
continue
|
|
||||||
|
|
||||||
output_path = output_dir / f"calendar_{spec.key}_{year}.png"
|
|
||||||
plot_calendar_heatmap(
|
|
||||||
matrix=matrix,
|
|
||||||
output_path=output_path,
|
|
||||||
title=spec.title_template.format(year=year, label=spec.agg_label),
|
|
||||||
cmap=spec.cmap,
|
|
||||||
colorbar_label=spec.colorbar_label,
|
|
||||||
)
|
|
||||||
results.append(CalendarHeatmapResult(spec=spec, output_path=output_path.resolve()))
|
|
||||||
|
|
||||||
return results
|
|
||||||
216
scripts/plot_calendar_overview.py
Normal file
216
scripts/plot_calendar_overview.py
Normal file
@ -0,0 +1,216 @@
|
|||||||
|
# scripts/plot_calendar_overview.py
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
|
import calendar
|
||||||
|
import numpy as np
|
||||||
|
import pandas as pd
|
||||||
|
import matplotlib.pyplot as plt
|
||||||
|
|
||||||
|
from meteo.dataset import load_raw_csv
|
||||||
|
from meteo.analysis import compute_daily_rainfall_totals
|
||||||
|
from meteo.plots import export_plot_dataset, plot_calendar_heatmap, plot_weekday_profiles
|
||||||
|
from meteo.variables import VARIABLES_BY_KEY
|
||||||
|
|
||||||
|
|
||||||
|
CSV_PATH = Path("data/weather_minutely.csv")
|
||||||
|
OUTPUT_DIR = Path("figures/calendar")
|
||||||
|
|
||||||
|
WEEKDAY_VARIABLE_KEYS = ["temperature", "humidity", "wind_speed", "illuminance"]
|
||||||
|
|
||||||
|
|
||||||
|
def _format_calendar_matrix(series: pd.Series, year: int, agg_label: str) -> pd.DataFrame:
|
||||||
|
"""
|
||||||
|
Transforme une série quotidienne en matrice mois x jours (1-31).
|
||||||
|
"""
|
||||||
|
start = pd.Timestamp(year=year, month=1, day=1, tz=series.index.tz)
|
||||||
|
end = pd.Timestamp(year=year, month=12, day=31, tz=series.index.tz)
|
||||||
|
filtered = series.loc[(series.index >= start) & (series.index <= end)]
|
||||||
|
|
||||||
|
matrix = pd.DataFrame(
|
||||||
|
np.nan,
|
||||||
|
index=[calendar.month_name[m][:3] for m in range(1, 13)],
|
||||||
|
columns=list(range(1, 32)),
|
||||||
|
)
|
||||||
|
|
||||||
|
for timestamp, value in filtered.items():
|
||||||
|
month = timestamp.month
|
||||||
|
day = timestamp.day
|
||||||
|
matrix.at[calendar.month_name[month][:3], day] = value
|
||||||
|
|
||||||
|
matrix.index.name = f"{agg_label} ({year})"
|
||||||
|
return matrix
|
||||||
|
|
||||||
|
|
||||||
|
def compute_daily_mean(df: pd.DataFrame, column: str) -> pd.Series:
|
||||||
|
return df[column].resample("1D").mean()
|
||||||
|
|
||||||
|
|
||||||
|
def plot_combined_calendar(
|
||||||
|
matrices: dict[str, pd.DataFrame],
|
||||||
|
output_path: Path,
|
||||||
|
*,
|
||||||
|
title: str,
|
||||||
|
) -> None:
|
||||||
|
if not matrices:
|
||||||
|
return
|
||||||
|
|
||||||
|
combined_dataset = pd.concat(matrices, axis=1)
|
||||||
|
export_plot_dataset(combined_dataset, output_path)
|
||||||
|
|
||||||
|
n = len(matrices)
|
||||||
|
fig, axes = plt.subplots(n, 1, figsize=(14, 4 * n), sharex=True)
|
||||||
|
if n == 1:
|
||||||
|
axes = [axes]
|
||||||
|
|
||||||
|
for ax, (label, matrix) in zip(axes, matrices.items()):
|
||||||
|
data = matrix.to_numpy(dtype=float)
|
||||||
|
im = ax.imshow(data, aspect="auto", interpolation="nearest", cmap=matrix.attrs.get("cmap", "viridis"))
|
||||||
|
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_ylabel(label)
|
||||||
|
cbar = fig.colorbar(im, ax=ax)
|
||||||
|
if matrix.attrs.get("colorbar_label"):
|
||||||
|
cbar.set_label(matrix.attrs["colorbar_label"])
|
||||||
|
|
||||||
|
axes[-1].set_xlabel("Jour du mois")
|
||||||
|
fig.suptitle(title)
|
||||||
|
fig.tight_layout(rect=[0, 0, 1, 0.97])
|
||||||
|
fig.savefig(output_path, dpi=150)
|
||||||
|
plt.close(fig)
|
||||||
|
|
||||||
|
|
||||||
|
def main() -> None:
|
||||||
|
if not CSV_PATH.exists():
|
||||||
|
print(f"⚠ Fichier introuvable : {CSV_PATH}")
|
||||||
|
return
|
||||||
|
|
||||||
|
df = load_raw_csv(CSV_PATH)
|
||||||
|
if df.empty:
|
||||||
|
print("⚠ Dataset vide.")
|
||||||
|
return
|
||||||
|
|
||||||
|
if not isinstance(df.index, pd.DatetimeIndex):
|
||||||
|
print("⚠ Le dataset doit avoir un index temporel.")
|
||||||
|
return
|
||||||
|
|
||||||
|
print(f"Dataset minuté chargé : {CSV_PATH}")
|
||||||
|
print(f" Lignes : {len(df)}")
|
||||||
|
print(f" Colonnes : {list(df.columns)}")
|
||||||
|
print()
|
||||||
|
|
||||||
|
OUTPUT_DIR.mkdir(parents=True, exist_ok=True)
|
||||||
|
|
||||||
|
latest_year = df.index.year.max()
|
||||||
|
print(f"Année retenue pour le calendrier : {latest_year}")
|
||||||
|
|
||||||
|
daily_totals = compute_daily_rainfall_totals(df=df)
|
||||||
|
daily_rain = daily_totals["daily_total"]
|
||||||
|
rain_matrix = _format_calendar_matrix(daily_rain, latest_year, "Pluie (mm)")
|
||||||
|
rain_matrix.attrs["cmap"] = "Blues"
|
||||||
|
rain_matrix.attrs["colorbar_label"] = "mm"
|
||||||
|
rain_path = OUTPUT_DIR / f"calendar_rain_{latest_year}.png"
|
||||||
|
plot_calendar_heatmap(
|
||||||
|
matrix=rain_matrix,
|
||||||
|
output_path=rain_path,
|
||||||
|
title=f"Pluie quotidienne - {latest_year}",
|
||||||
|
cmap="Blues",
|
||||||
|
colorbar_label="mm",
|
||||||
|
)
|
||||||
|
print(f"✔ Heatmap pluie {latest_year} : {rain_path}")
|
||||||
|
|
||||||
|
daily_temp = compute_daily_mean(df, "temperature")
|
||||||
|
temp_matrix = _format_calendar_matrix(daily_temp, latest_year, "Température (°C)")
|
||||||
|
temp_matrix.attrs["cmap"] = "coolwarm"
|
||||||
|
temp_matrix.attrs["colorbar_label"] = "°C"
|
||||||
|
temp_path = OUTPUT_DIR / f"calendar_temperature_{latest_year}.png"
|
||||||
|
plot_calendar_heatmap(
|
||||||
|
matrix=temp_matrix,
|
||||||
|
output_path=temp_path,
|
||||||
|
title=f"Température moyenne quotidienne - {latest_year}",
|
||||||
|
cmap="coolwarm",
|
||||||
|
colorbar_label="°C",
|
||||||
|
)
|
||||||
|
print(f"✔ Heatmap température {latest_year} : {temp_path}")
|
||||||
|
|
||||||
|
matrices_for_combined = {
|
||||||
|
"Pluie (mm)": rain_matrix,
|
||||||
|
"Température (°C)": temp_matrix,
|
||||||
|
}
|
||||||
|
|
||||||
|
if "pressure" in df.columns:
|
||||||
|
daily_pressure = compute_daily_mean(df, "pressure")
|
||||||
|
pressure_matrix = _format_calendar_matrix(daily_pressure, latest_year, "Pression (hPa)")
|
||||||
|
pressure_matrix.attrs["cmap"] = "Greens"
|
||||||
|
pressure_matrix.attrs["colorbar_label"] = "hPa"
|
||||||
|
pressure_path = OUTPUT_DIR / f"calendar_pressure_{latest_year}.png"
|
||||||
|
plot_calendar_heatmap(
|
||||||
|
matrix=pressure_matrix,
|
||||||
|
output_path=pressure_path,
|
||||||
|
title=f"Pression moyenne quotidienne - {latest_year}",
|
||||||
|
cmap="Greens",
|
||||||
|
colorbar_label="hPa",
|
||||||
|
)
|
||||||
|
print(f"✔ Heatmap pression {latest_year} : {pressure_path}")
|
||||||
|
matrices_for_combined["Pression (hPa)"] = pressure_matrix
|
||||||
|
|
||||||
|
if "illuminance" in df.columns:
|
||||||
|
daily_lux = compute_daily_mean(df, "illuminance")
|
||||||
|
lux_matrix = _format_calendar_matrix(daily_lux, latest_year, "Illuminance (lux)")
|
||||||
|
lux_matrix.attrs["cmap"] = "YlOrBr"
|
||||||
|
lux_matrix.attrs["colorbar_label"] = "lux"
|
||||||
|
lux_path = OUTPUT_DIR / f"calendar_illuminance_{latest_year}.png"
|
||||||
|
plot_calendar_heatmap(
|
||||||
|
matrix=lux_matrix,
|
||||||
|
output_path=lux_path,
|
||||||
|
title=f"Illuminance moyenne quotidienne - {latest_year}",
|
||||||
|
cmap="YlOrBr",
|
||||||
|
colorbar_label="lux",
|
||||||
|
)
|
||||||
|
print(f"✔ Heatmap illuminance {latest_year} : {lux_path}")
|
||||||
|
matrices_for_combined["Illuminance (lux)"] = lux_matrix
|
||||||
|
|
||||||
|
if "wind_speed" in df.columns:
|
||||||
|
daily_wind = compute_daily_mean(df, "wind_speed")
|
||||||
|
wind_matrix = _format_calendar_matrix(daily_wind, latest_year, "Vent (km/h)")
|
||||||
|
wind_matrix.attrs["cmap"] = "Purples"
|
||||||
|
wind_matrix.attrs["colorbar_label"] = "km/h"
|
||||||
|
wind_path = OUTPUT_DIR / f"calendar_wind_{latest_year}.png"
|
||||||
|
plot_calendar_heatmap(
|
||||||
|
matrix=wind_matrix,
|
||||||
|
output_path=wind_path,
|
||||||
|
title=f"Vitesse moyenne du vent - {latest_year}",
|
||||||
|
cmap="Purples",
|
||||||
|
colorbar_label="km/h",
|
||||||
|
)
|
||||||
|
print(f"✔ Heatmap vent {latest_year} : {wind_path}")
|
||||||
|
matrices_for_combined["Vent (km/h)"] = wind_matrix
|
||||||
|
|
||||||
|
combined_path = OUTPUT_DIR / f"calendar_combined_{latest_year}.png"
|
||||||
|
plot_combined_calendar(
|
||||||
|
matrices=matrices_for_combined,
|
||||||
|
output_path=combined_path,
|
||||||
|
title=f"Calendrier combiné {latest_year}",
|
||||||
|
)
|
||||||
|
print(f"✔ Calendrier combiné : {combined_path}")
|
||||||
|
|
||||||
|
hourly = df[WEEKDAY_VARIABLE_KEYS].resample("1h").mean()
|
||||||
|
weekday_stats = hourly.groupby(hourly.index.dayofweek).mean()
|
||||||
|
weekday_path = OUTPUT_DIR / "weekday_profiles.png"
|
||||||
|
variables = [VARIABLES_BY_KEY[key] for key in WEEKDAY_VARIABLE_KEYS]
|
||||||
|
plot_weekday_profiles(
|
||||||
|
weekday_df=weekday_stats,
|
||||||
|
variables=variables,
|
||||||
|
output_path=weekday_path,
|
||||||
|
title="Profils moyens par jour de semaine",
|
||||||
|
)
|
||||||
|
print(f"✔ Profils hebdomadaires : {weekday_path}")
|
||||||
|
|
||||||
|
print("✔ Graphiques calendrier générés.")
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
||||||
@ -29,10 +29,7 @@ PLOT_SCRIPTS: tuple[PlotScript, ...] = (
|
|||||||
"plot_basic_variables",
|
"plot_basic_variables",
|
||||||
PROJECT_ROOT / "docs" / "03 - Premiers graphiques" / "scripts" / "plot_basic_variables.py",
|
PROJECT_ROOT / "docs" / "03 - Premiers graphiques" / "scripts" / "plot_basic_variables.py",
|
||||||
),
|
),
|
||||||
PlotScript(
|
PlotScript("plot_calendar_overview", PROJECT_ROOT / "scripts" / "plot_calendar_overview.py"),
|
||||||
"plot_calendar_overview",
|
|
||||||
PROJECT_ROOT / "docs" / "03 - Premiers graphiques" / "scripts" / "plot_calendar_overview.py",
|
|
||||||
),
|
|
||||||
PlotScript(
|
PlotScript(
|
||||||
"plot_all_pairwise_scatter",
|
"plot_all_pairwise_scatter",
|
||||||
PROJECT_ROOT / "docs" / "04 - Corrélations binaires" / "scripts" / "plot_all_pairwise_scatter.py",
|
PROJECT_ROOT / "docs" / "04 - Corrélations binaires" / "scripts" / "plot_all_pairwise_scatter.py",
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user