Spaces:
Runtime error
Runtime error
import pandas as pd # stress hydrique and rendement, besoin en eau | |
import plotly.graph_objects as go | |
from typing import List | |
import plotly.express as px | |
from data_pipelines.historical_weather_data import ( | |
download_historical_weather_data, | |
aggregate_hourly_weather_data, | |
) | |
import os | |
from forecast import get_forecast_data | |
from compute_et0_adjusted import compute_et0 | |
import copy | |
def water_deficit(df, latitude, longitude, shading_coef=0, historic=True): | |
preprocessed_data = df.copy() | |
preprocessed_data["irradiance"] = preprocessed_data[ | |
"Surface Downwelling Shortwave Radiation (W/m²)" | |
] * (1 - shading_coef) | |
preprocessed_data["air_temperature_min"] = preprocessed_data[ | |
"Daily Minimum Near Surface Air Temperature (°C)" | |
] | |
preprocessed_data["air_temperature_max"] = preprocessed_data[ | |
"Daily Maximum Near Surface Air Temperature (°C)" | |
] | |
if historic == True: | |
preprocessed_data["relative_humidity_min"] = preprocessed_data[ | |
"Relative Humidity_min" | |
] | |
preprocessed_data["relative_humidity_max"] = preprocessed_data[ | |
"Relative Humidity_max" | |
] | |
else: | |
preprocessed_data["relative_humidity_min"] = preprocessed_data[ | |
"Relative Humidity (%)" | |
] | |
preprocessed_data["relative_humidity_max"] = preprocessed_data[ | |
"Relative Humidity (%)" | |
] | |
preprocessed_data["wind_speed"] = preprocessed_data["Near Surface Wind Speed (m/s)"] | |
preprocessed_data["time"] = pd.to_datetime( | |
preprocessed_data["time"], errors="coerce" | |
) | |
preprocessed_data["month"] = preprocessed_data["time"].dt.month | |
preprocessed_data["day_of_year"] = preprocessed_data["time"].dt.dayofyear | |
et0 = compute_et0(preprocessed_data, latitude, longitude) | |
preprocessed_data["Evaporation (mm/day)"] = et0 | |
preprocessed_data["Evaporation (mm/day)"] = preprocessed_data[ | |
"Evaporation (mm/day)" | |
].clip(lower=0) | |
preprocessed_data["Precipitation (mm/day)"] = ( | |
86400 * preprocessed_data["Precipitation (kg m-2 s-1)"] | |
) | |
preprocessed_data["Water Deficit (mm/day)"] = ( | |
preprocessed_data["Evaporation (mm/day)"] | |
- preprocessed_data["Precipitation (mm/day)"] | |
) | |
return preprocessed_data | |
def concatenate_historic_forecast( | |
historic, forecast, cols_to_keep, value_period_col="forecast scénario modéré", don_t = False | |
): | |
if don_t: | |
historic["period"] = value_period_col | |
forecast["period"] = value_period_col | |
historic = historic[cols_to_keep] | |
forecast = forecast[cols_to_keep] | |
full_data = pd.concat([historic, forecast]) | |
full_data = full_data[full_data['year']>=2025] | |
return full_data | |
historic["period"] = "historique" | |
forecast["period"] = value_period_col | |
historic = historic[cols_to_keep] | |
forecast = forecast[cols_to_keep] | |
full_data = pd.concat([historic, forecast]) | |
return full_data | |
def visualize_climate( | |
moderate: pd.DataFrame, | |
historic: pd.DataFrame, | |
pessimist: pd.DataFrame, | |
x_axis="year", | |
column: str = "Precipitation (mm)", | |
cols_to_keep: List[str] = [ | |
"Precipitation (mm)", | |
"Near Surface Air Temperature (°C)", | |
"Surface Downwelling Shortwave Radiation (W/m²)", | |
"Water Deficit (mm/day)", | |
"year", | |
"period", | |
], | |
): | |
if column == "Water Deficit (mm/day)": | |
concatenated_moderate = concatenate_historic_forecast( | |
historic, moderate, cols_to_keep,don_t=True | |
) | |
else: | |
concatenated_moderate = concatenate_historic_forecast( | |
historic, moderate, cols_to_keep | |
) | |
concatenated_moderate = concatenated_moderate.sort_values(by=x_axis) # Ensure order | |
fig = go.Figure() | |
if column == "Precipitation (mm)": | |
for condition_value in concatenated_moderate["period"].unique(): | |
segment = concatenated_moderate[ | |
concatenated_moderate["period"] == condition_value | |
] | |
avg_precipitation = segment.groupby(x_axis)[column].mean().reset_index() | |
fig.add_trace( | |
go.Bar( | |
x=avg_precipitation[x_axis], | |
y=avg_precipitation[column], | |
name=f"{condition_value}", | |
marker=dict( | |
color="blue" if condition_value == "historique" else "purple" | |
), | |
) | |
) | |
if column == "Water Deficit (mm/day)": | |
concatenated_pessimist = concatenate_historic_forecast( | |
historic, pessimist, cols_to_keep, "forecast scénario pessimiste",don_t=True | |
) | |
else: | |
concatenated_pessimist = concatenate_historic_forecast( | |
historic, pessimist, cols_to_keep, "forecast scénario pessimiste" | |
) | |
concatenated_pessimist = concatenated_pessimist.sort_values(by=x_axis) | |
concatenated_pessimist = concatenated_pessimist[ | |
concatenated_pessimist["period"] != "historique" | |
] | |
for condition_value in concatenated_pessimist["period"].unique(): | |
segment = concatenated_pessimist[ | |
concatenated_pessimist["period"] == condition_value | |
] | |
avg_precipitation = segment.groupby(x_axis)[column].mean().reset_index() | |
fig.add_trace( | |
go.Bar( | |
x=avg_precipitation[x_axis], | |
y=avg_precipitation[column], | |
name=f"{condition_value}", | |
marker=dict( | |
color="orange" if condition_value != "historique" else "blue" | |
), | |
) | |
) | |
# Update layout for bar chart | |
fig.update_layout( | |
title=f"Moyenne de {column} par année", | |
xaxis_title="Année", # Set the x-axis title to Year | |
yaxis_title="Précipitation (mm)", # Set the y-axis title to Precipitation | |
barmode="group", # Group bars for different conditions | |
) | |
else: | |
for condition_value in concatenated_moderate["period"].unique(): | |
segment = concatenated_moderate[ | |
concatenated_moderate["period"] == condition_value | |
] | |
if condition_value == "historique": | |
fig.add_trace( | |
go.Scatter( | |
x=segment[x_axis], # Years on x-axis | |
y=segment[column], # Precipitation values on y-axis | |
mode="lines", | |
name=f"{condition_value}", | |
legendgroup="group1", | |
showlegend=False, | |
line=dict( | |
color=( | |
"blue" if condition_value == "historique" else "purple" | |
) | |
), | |
) | |
) | |
else: | |
fig.add_trace( | |
go.Scatter( | |
x=segment[x_axis], # Years on x-axis | |
y=segment[column], # Precipitation values on y-axis | |
mode="lines", | |
name=f"{condition_value}", | |
legendgroup="group2", | |
showlegend=False, | |
line=dict( | |
color=( | |
"blue" if condition_value == "historique" else "purple" | |
), | |
dash="dot", | |
), | |
) | |
) | |
# Continue with pessimistic data as in the original function... | |
if column == "Water Deficit (mm/day)": | |
concatenated_pessimist = concatenate_historic_forecast( | |
historic, pessimist, cols_to_keep, "forecast scénario pessimiste",don_t=True | |
) | |
else: | |
concatenated_pessimist = concatenate_historic_forecast( | |
historic, pessimist, cols_to_keep, "forecast scénario pessimiste" | |
) | |
concatenated_pessimist = concatenated_pessimist.sort_values(by=x_axis) | |
for condition_value in concatenated_pessimist["period"].unique(): | |
segment = concatenated_pessimist[ | |
concatenated_pessimist["period"] == condition_value | |
] | |
if condition_value == "historique": | |
fig.add_trace( | |
go.Scatter( | |
x=segment[x_axis], # Years on x-axis | |
y=segment[column], # Precipitation values on y-axis | |
mode="lines", | |
name=f"{condition_value}", | |
legendgroup="group1", | |
line=dict( | |
color=( | |
"blue" if condition_value == "historique" else "orange" | |
), | |
dash="dot" if condition_value != "historique" else None, | |
), | |
) | |
) | |
else: | |
fig.add_trace( | |
go.Scatter( | |
x=segment[x_axis], # Years on x-axis | |
y=segment[column], # Precipitation values on y-axis | |
mode="lines", | |
name=f"{condition_value}", | |
legendgroup="group3", | |
line=dict( | |
color=( | |
"blue" if condition_value == "historique" else "orange" | |
), | |
dash="dot" if condition_value != "historique" else None, | |
), | |
) | |
) | |
# Interpolation for the pessimistic scenario... | |
interpolation_pessimist = concatenated_pessimist[ | |
concatenated_pessimist[x_axis] > 2023 | |
] | |
interpolation_pessimist = interpolation_pessimist[ | |
interpolation_pessimist[x_axis] <= 2025 | |
] | |
fig.add_trace( | |
go.Scatter( | |
x=interpolation_pessimist[x_axis], | |
y=interpolation_pessimist[column].interpolate(), | |
mode="lines", | |
name="forecast scénario pessimiste", | |
legendgroup="group3", | |
showlegend=False, | |
line=dict(color="orange", dash="dot"), | |
), | |
) | |
interpolation_moderate = concatenated_moderate[ | |
concatenated_moderate[x_axis] > 2023 | |
] | |
interpolation_moderate = interpolation_moderate[ | |
interpolation_moderate[x_axis] <= 2025 | |
] | |
fig.add_trace( | |
go.Scatter( | |
x=interpolation_moderate[x_axis], | |
y=interpolation_moderate[column].interpolate(), | |
mode="lines", | |
name="forecast scénario modéré", | |
legendgroup="group2", | |
line=dict(color="purple", dash="dot"), | |
), | |
) | |
fig.update_layout( | |
title=f"Historique et Forecast pour {column}", | |
xaxis_title="Year", # Set the x-axis title to Year | |
yaxis_title=column, # Set the y-axis title to Precipitation | |
) | |
return fig | |
def aggregate_yearly(df, col_to_agg, operation="mean"): | |
df[col_to_agg] = df.groupby("year")[col_to_agg].transform(operation) | |
return df | |
def generate_plots( | |
moderate: pd.DataFrame, | |
historic: pd.DataFrame, | |
pessimist: pd.DataFrame, | |
x_axes: List[str], | |
cols_to_plot: List[str], | |
is_shaded: str = "", | |
): | |
plots = [] | |
for i, col in enumerate(cols_to_plot): | |
plots.append(visualize_climate(moderate, historic, pessimist, x_axes[i], col)) | |
return plots | |
def get_plots(): | |
cols_to_plot = [ | |
"Precipitation (mm)", | |
"Near Surface Air Temperature (°C)", | |
"Surface Downwelling Shortwave Radiation (W/m²)", | |
"Water Deficit (mm/day)", | |
] | |
cols_to_keep: List[str] = [ | |
"Precipitation (mm)", | |
"Near Surface Air Temperature (°C)", | |
"Surface Downwelling Shortwave Radiation (W/m²)", | |
"Water Deficit (mm/day)", | |
"year", | |
"period", | |
] | |
x_axes = ["year"] * len(cols_to_plot) | |
latitude = 47 | |
longitude = 5 | |
start_year = 2000 | |
end_year = 2025 | |
df = download_historical_weather_data(latitude, longitude, start_year, end_year) | |
historic = aggregate_hourly_weather_data(df) | |
historic = historic.reset_index() | |
historic = historic.rename( | |
columns={ | |
"precipitation": "Precipitation (mm)", | |
"air_temperature_mean": "Near Surface Air Temperature (°C)", | |
"irradiance": "Surface Downwelling Shortwave Radiation (W/m²)", | |
"index": "time", | |
} | |
) | |
historic["time"] = pd.to_datetime(historic["time"]) | |
historic = historic.sort_values("time") | |
historic = historic[historic["time"] < "2025-01-01"] | |
historic = historic.rename( | |
columns={ | |
"air_temperature_min": "Daily Minimum Near Surface Air Temperature (°C)", | |
"air_temperature_max": "Daily Maximum Near Surface Air Temperature (°C)", | |
"relative_humidity_min": "Relative Humidity_min", | |
"relative_humidity_max": "Relative Humidity_max", | |
"wind_speed": "Near Surface Wind Speed (m/s)", | |
"Precipitation (mm)": "Precipitation (kg m-2 s-1)", | |
} | |
) | |
historic["Precipitation (kg m-2 s-1)"] = ( | |
historic["Precipitation (kg m-2 s-1)"] / 3600 | |
) | |
historic = water_deficit(historic, latitude, longitude) | |
historic = historic.rename( | |
columns={"Precipitation (kg m-2 s-1)": "Precipitation (mm)"} | |
) | |
historic["Precipitation (mm)"] = historic["Precipitation (mm)"] * 3600 | |
moderate = get_forecast_data(latitude, longitude, "moderate") | |
pessimist = get_forecast_data(latitude, longitude, "pessimist") | |
moderate = moderate.rename( | |
columns={"Precipitation (kg m-2 s-1)": "Precipitation (mm)"} | |
) | |
moderate["time"] = pd.to_datetime(moderate["time"]) | |
moderate = moderate.sort_values("time") | |
moderate["year"] = moderate["time"].dt.year | |
moderate["Precipitation (mm)"] = moderate["Precipitation (mm)"] * 31536000 | |
pessimist = pessimist.rename( | |
columns={"Precipitation (kg m-2 s-1)": "Precipitation (mm)"} | |
) | |
pessimist["time"] = pd.to_datetime(pessimist["time"]) | |
pessimist = pessimist.sort_values("time") | |
pessimist["year"] = pessimist["time"].dt.year | |
pessimist["Precipitation (mm)"] = pessimist["Precipitation (mm)"] * 31536000 | |
pessimist["period"] = "forecast scénario pessimiste" | |
historic["year"] = historic["time"].dt.year | |
historic["Precipitation (mm)"] = historic["Precipitation (mm)"] * 8760.0 | |
for col in cols_to_plot: | |
moderate = aggregate_yearly(moderate, col) | |
historic = aggregate_yearly(historic, col) | |
pessimist = aggregate_yearly(pessimist, col) | |
plots = generate_plots(moderate, historic, pessimist, x_axes, cols_to_plot) | |
moderate = get_forecast_data(latitude, longitude, "moderate", shading_coef=0.2) | |
pessimist = get_forecast_data(latitude, longitude, "pessimist", shading_coef=0.2) | |
pessimist["year"] = pessimist["time"].dt.year | |
pessimist = pessimist[["year", "Water Deficit (mm/day)"]] | |
pessimist = aggregate_yearly(pessimist, 'Water Deficit (mm/day)') | |
plot_ombrage = copy.deepcopy(plots[-1]) | |
plot_ombrage.add_trace( | |
go.Scatter( | |
x=pessimist["year"], | |
y=pessimist['Water Deficit (mm/day)'], | |
mode="lines", | |
name="forecast scénario pessimisste ombrage de 20%", | |
line=dict( | |
color="green", | |
dash="dot", | |
), | |
) | |
) | |
plots.append(plot_ombrage) | |
return plots | |