La zonificación del POT no cambia con el clima, pero la lluvia que detona los movimientos sí. Esta página estima el cambio en los índices de lluvia extrema Rx1day, Rx5day y R95pTOT Zhang et al., 2011 bajo los escenarios SSP2-4.5 y SSP5-8.5 Riahi et al., 2017O'Neill et al., 2017, aplicando el cambio de la precipitación de NEX-GDDP-CMIP6 Thrasher et al., 2022 a la serie local (método delta multiplicativo).
Deltas de precipitación¶
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
from IPython.display import display
from sidro.analisis import clima
from sidro.config import aoi_cfg, parametros
from sidro.fetch import obtener_capa
MODELOS = None # p. ej. ["ACCESS-CM2", "EC-Earth3"] para una prueba rápida
cfg = aoi_cfg()["clima"]
serie = intentar(obtener_capa, "clima_observado_diario", mensaje="No se pudo obtener la serie climática diaria")
pr = serie["precipitation_sum"] if serie is not None and "precipitation_sum" in serie.columns else None
deltas = None
if pr is not None:
deltas = intentar(clima.deltas_tabla, ["pr"], cfg["escenarios"], cfg["horizontes"], MODELOS,
cache="deltas_mov_masa",
mensaje="No se pudieron obtener las proyecciones CMIP6 (requiere acceso a Planetary Computer)")
if deltas is not None:
display(deltas.groupby(["escenario", "horizonte"])["delta"].describe()[["count", "min", "50%", "max"]].round(3))La tabla muestra, por escenario y horizonte, la razón futuro/histórico de la precipitación media entre modelos (1,0 = sin cambio).
Cambio en los índices de lluvia extrema¶
cambios = None
if deltas is not None:
indices_lluvia = parametros()["movimientos_masa"]["indices_lluvia"]
q = cfg["percentiles_ensamble"]
filas = []
for (esc, hor), g in deltas.groupby(["escenario", "horizonte"]):
razon = pd.DataFrame([clima.cambio_lluvia_extrema(pr, d) for d in g["delta"]])[indices_lluvia]
for ind in indices_lluvia:
filas.append({"escenario": esc, "horizonte": hor, "índice": ind,
**{f"p{x}": 100 * (np.percentile(razon[ind], x) - 1) for x in q}})
cambios = pd.DataFrame(filas)
display(cambios.round(1))Cada valor es el cambio porcentual del promedio anual del índice respecto de la serie observada (p10, p50 y p90 entre modelos). R95pTOT suele cambiar más (en valor absoluto) que los otros porque su umbral de día muy húmedo se fija en el periodo base: al escalar la lluvia, más o menos días lo superan.
if cambios is not None:
fig, ax = plt.subplots(figsize=(7, 3.4))
r1 = cambios[cambios["índice"] == "rx1day"]
x = np.arange(len(r1))
med = r1[f"p{q[1]}"].values
ax.bar(x, med, yerr=[med - r1[f"p{q[0]}"].values, r1[f"p{q[2]}"].values - med], color="#3a6ea5", capsize=4)
ax.set_xticks(x, [f"{e}\n{h}" for e, h in zip(r1.escenario, r1.horizonte)], fontsize=8)
ax.set_ylabel("Cambio en Rx1day (%)"), ax.axhline(0, color="#555", lw=0.8)
fig
Niveles de retorno futuros del Rx1day¶
Con el método delta multiplicativo, la lluvia de un día con periodo de retorno se escala por la misma razón que el Rx1day medio. Se aplica el cambio (p50, con p10–p90 entre modelos) a los niveles de retorno históricos de 3.3.b: una lluvia que hoy se espera cada 50 años pasa a tener ese valor mayor, o, dicho al revés, la lluvia histórica de 50 años pasa a ser más frecuente.
niveles_futuros = None
if cambios is not None and "precipitation_sum" in serie.columns:
hist = clima.niveles_retorno_gev(clima.indices_precipitacion(serie["precipitation_sum"])["rx1day"], distribucion="gumbel")
r1 = cambios[cambios["índice"] == "rx1day"].set_index(["escenario", "horizonte"])
cols = {"histórico": hist.set_index("periodo")["nivel"]}
for (esc, hor), fila in r1.iterrows():
cols[f"{esc} {hor}"] = hist.set_index("periodo")["nivel"] * (1 + fila[f"p{q[1]}"] / 100)
niveles_futuros = pd.DataFrame(cols).rename_axis("periodo de retorno (años)")
display(niveles_futuros.round(0))
fig, ax = plt.subplots(figsize=(6.5, 3.4))
for col in niveles_futuros:
ax.plot(niveles_futuros.index, niveles_futuros[col], label=col, lw=2 if col == "histórico" else 1.2,
color="#333" if col == "histórico" else None)
ax.set_xscale("log"), ax.set_xlabel("Periodo de retorno (años)"), ax.set_ylabel("Rx1day (mm)")
ax.legend(fontsize=7), ax.grid(alpha=0.3)
fig
Es una extrapolación sobre una extrapolación: ajuste a ~30 años con ERA5 (~25 km), más un factor de cambio medio. Sirve para ordenar escenarios, no para dimensionar obras.
Guardar el resumen¶
if cambios is not None:
from sidro import export
export.guardar_resumen("mov_masa_escenarios", {"cambio_lluvia_pct": cambios.to_dict("records")})- Zhang, X., Alexander, L., Hegerl, G. C., & others. (2011). Indices for monitoring changes in extremes based on daily temperature and precipitation data. WIREs Climate Change, 2, 851–870. 10.1002/wcc.147
- Riahi, K., van Vuuren, D. P., Kriegler, E., & others. (2017). The Shared Socioeconomic Pathways and their energy, land use, and greenhouse gas emissions implications: An overview. Global Environmental Change, 42, 153–168. 10.1016/j.gloenvcha.2016.05.009
- O’Neill, B. C., Kriegler, E., Ebi, K. L., & others. (2017). The roads ahead: Narratives for shared socioeconomic pathways describing world futures in the 21st century. Global Environmental Change, 42, 169–180. 10.1016/j.gloenvcha.2015.01.004
- Thrasher, B., Wang, W., Michaelis, A., Melton, F., Lee, T., & Nemani, R. (2022). NASA Global Daily Downscaled Projections, CMIP6. Scientific Data, 9, 262. 10.1038/s41597-022-01393-4