
Figure 1:Acumulado de precipitación en el radar de Guaviare
Estimación Cuantitativa de la Lluvia¶
🧭 Introducción¶
En este cuadernillo aprenderás cómo estimar la lluvia acumulada (QPE, Quantitative Precipitation Estimation) a partir de datos de reflectividad. Usaremos una relación empírica Z–R para convertir reflectividad en tasa de precipitación, y luego integraremos en el tiempo para obtener acumulados.
Los datos provienen del radar meteorológico ubicado en Guaviare, Colombia, y están preprocesados en formato Zarr siguiendo los principios FAIR.
📚 ¿Qué vas a aprender?¶
✔ Cómo aplicar relaciones Z–R para estimar lluvia a partir de reflectividad
✔ Cómo calcular acumulados de precipitación sobre tiempo con datos radar
✔ Cómo visualizar mapas de lluvia en 2D usando xarray
y matplotlib
✔ Cómo usar datos radar del radar Guaviare desde Zarr en la nube
✅ Requisitos Previos¶
Concepto | Importancia | Enlace sugerido |
---|---|---|
Python y Xarray | Manipulación de datos multidimensionales | Intro Xarray |
Radar meteorológico | Interpretación física de la reflectividad (dBZ) | Radar básico |
1. ☔ Fundamento: Estimación Cuantitativa de Precipitación (QPE)¶
La estimación cuantitativa de precipitación (QPE) consiste en transformar la reflectividad medida por el radar (en unidades dBZ) a una tasa de precipitación (mm/h), usando una relación empírica del tipo:
Una de las más utilizadas es la relación de Marshall y Palmer (1948):
from dask.distributed import Client, LocalCluster
# Create a local cluster with correct arguments
cluster = LocalCluster(
n_workers=4, # Number of worker processes
memory_limit='2GB' # Per worker memory limit
)
client = Client(cluster)
client
2. 🗂️ Acceso a datos del radar de Guaviare¶
En esta sección accederemos a datos del radar meteorológico ubicado en San José del Guaviare, Colombia. Estos datos han sido preprocesados y almacenados en formato Zarr v3, siguiendo los principios FAIR (Findable, Accessible, Interoperable, Reusable), y se encuentran disponibles públicamente a través del servicio en la nube Jetstream 2.
Usaremos xarray
y fsspec
import xarray as xr
# URL del endpoint S3 en Jetstream 2
url = "https://js2.jetstream-cloud.org:8001/"
path = "s3://pythia/radar/AtmosCol2025/Guaviare.zarr"
# Abrir el DataTree del radar
dtree = xr.open_datatree(
path,
# "/media/alfonso/drive/Alfonso/python/raw2zarr/zarr/Guaviare.zarr",
engine="zarr",
chunks={},
backend_kwargs={
"consolidated": False,
"storage_options": {
"anon": True,
"client_kwargs": {
"endpoint_url": url,
},
},
},
)
display(dtree)
2.1 🔍 Exploración de la estructura del volumen radar¶
El radar de San José del Guaviare contiene múltiples modos de escaneo organizados como grupos dentro del DataTree
, tales como PRECA
, PRECB
, PRECC
y SURVP
. Cada uno corresponde a una configuración de volumen distinta en el modo de precipitación.
Dentro de cada grupo se encuentran:
- Variables globales (
latitude
,longitude
,altitude
, etc.) - Subgrupos de barrido (
sweep_0
,sweep_1
,sweep_2
, ...) - Parámetros del radar (
radar_parameters
) - Correcciones de georreferenciación (
georeferencing_correction
)
list(dtree.children)
['PRECA', 'SURVP', 'PRECB', 'PRECC']
Y los nodos hijos dentro de un volumen específico, por ejemplo PRECA
:
list(dtree["PRECA"].children)
['georeferencing_correction',
'radar_parameters',
'sweep_3',
'sweep_0',
'sweep_1',
'sweep_2']
dtree["/PRECA/sweep_0/DBZH"]
3. 🌧️ Cálculo de la Precipitación Acumulada¶
En esta sección estimaremos la profundidad de precipitación acumulada usando la reflectividad radar de Guaviare y una relación empírica tipo ( Z = a \cdot R^b ). Para ello, aplicaremos la fórmula de Marshall y Palmer y realizaremos una integración temporal sobre cada píxel.
La función rain_depth()
implementa este proceso completo de forma vectorizada usando xarray
.
3.1 Definición de la función rain_depth
¶
def rain_depth(
z: xr.DataArray, a: float = 200.0, b: float = 1.6, t: int = 5
) -> xr.DataArray:
"""
Estima la profundidad de precipitación acumulada a partir de la reflectividad radar.
Parámetros
----------
z : xr.DataArray
Reflectividad en dBZ o Z lineal (se determina automáticamente por las unidades).
a : float, opcional
Parámetro 'a' en la relación Z-R. Valor por defecto: 200.0.
b : float, opcional
Parámetro 'b' en la relación Z-R. Valor por defecto: 1.6.
t : int, opcional
Intervalo de tiempo en minutos entre volúmenes. Default: 5.
Retorna
-------
xr.DataArray
Profundidad de lluvia estimada (en mm) por píxel.
"""
# Revisión de unidades
units = z.attrs.get("units", "")
# Convertimos dBZ a Z lineal si es necesario
if units.startswith("dB"):
z_lin = 10 ** (z / 10)
else:
z_lin = z # ya está en unidades lineales
# Aplicamos la relación Z-R e integramos en el tiempo
r = ((1 / a) ** (1 / b)) * z_lin ** (1 / b)
return r * (t / 60) # profundidad acumulada en mm
3.2 Aplicación sobre datos del radar Guaviare (SURVP/sweep_0
)¶
Usamos el barrido más bajo (sweep_0
) del volumen SURVP
, que corresponde a una elevación cercana a (0.5^\circ), ideal para estimar precipitación acumulada sobre la superficie.
Seleccionamos la reflectividad horizontal (DBZH
) y aplicamos la función rain_depth
.
# Selección del barrido y variable de reflectividad
ref_log = dtree["/SURVP/sweep_0/DBZH"]
# Cálculo de la precipitación acumulada (en mm) para cada volumen
rr = rain_depth(ref_log)
rr
3.1 🧮 Estimación de la lluvia total acumulada¶
Una vez calculada la tasa de precipitación para cada volumen, podemos estimar la lluvia total acumulada del evento sumando a lo largo del tiempo (vcp_time
).
rr_total = rr.sum(dim="vcp_time", skipna=True)
rr_total
Visualizamos el campo acumulado:
%%time
rr_total.plot(x="x", y="y", cmap="magma", robust=True);
CPU times: user 2.22 s, sys: 193 ms, total: 2.41 s
Wall time: 14.1 s

3.2 🧮 Acumulaciones parciales por intervalo de tiempo¶
El volumen radar cubre el periodo:
- Inicio: 2025-06-19 18:19 UTC
- Fin: 2025-06-19 23:50 UTC
A continuación, estimaremos la lluvia acumulada para distintos intervalos:
- Primera hora del evento
- Primeras dos horas
- Evento completo
# Conversión explícita a datetime64 para selección
import numpy as np
import matplotlib.pyplot as plt
t0 = np.datetime64("2025-06-19T18:19:00")
t1 = np.datetime64("2025-06-19T19:19:00")
t2 = np.datetime64("2025-06-19T20:19:00")
# Subconjuntos únicos para cada intervalo
rr_sel_1h = rr.sel(vcp_time=slice(t0, t1))
rr_sel_2h = rr.sel(vcp_time=slice(t1, t2))
rr_sel_remain = rr.sel(vcp_time=slice(t2, None))
# Acumulaciones parciales
rr_1h = rr_sel_1h.sum("vcp_time")
rr_2h = rr_1h + rr_sel_2h.sum("vcp_time")
rr_total = rr_2h + rr_sel_remain.sum("vcp_time")
3.3 📊 Visualización de acumulaciones en distintos intervalos¶
A continuación, mostramos la estimación de lluvia acumulada para:
- Primer hora
- Primeras dos horas
- Evento completo
%%time
fig, axs = plt.subplots(1, 3, figsize=(12, 4), constrained_layout=True, sharey=True)
# Primer hora
rr_1h.plot(
ax=axs[0],
cmap="magma",
robust=True,
x="x",
y="y",
add_colorbar=False,
)
axs[0].set_title("Acumulado 1h")
axs[0].set_xlabel("Distancia Norte-Sur")
axs[0].set_ylabel("Distancia Este-Oeste")
# Dos horas
rr_2h.plot(
ax=axs[1],
cmap="magma",
robust=True,
x="x",
y="y",
add_colorbar=False,
)
axs[1].set_title("Acumulado 2h")
axs[1].set_ylabel("")
axs[1].set_xlabel("Distancia Este-Oeste")
# Evento completo
rr_total.plot(
ax=axs[2],
cmap="magma",
robust=True,
x="x",
y="y",
cbar_kwargs={"label": "Precipitación [mm]"},
)
axs[2].set_title("Acumulado total")
axs[2].set_ylabel("")
axs[2].set_xlabel("Distancia Este-Oeste")
plt.savefig("../images/qpe-car.png", dpi=150, bbox_inches='tight')
plt.show()

CPU times: user 8.99 s, sys: 572 ms, total: 9.56 s
Wall time: 37 s
5. ✅ Conclusiones¶
En este cuaderno exploramos el uso del radar meteorológico de Guaviare (Colombia) para realizar una estimación cuantitativa de precipitación (QPE) basada en reflectividad.
- Utilizamos datos en formato Zarr almacenados en la nube (Jetstream 2) para acceder y procesar reflectividades sin necesidad de descarga local.
- Aplicamos la relación empírica de Marshall y Palmer (1948) para convertir reflectividad (( Z )) en tasa de precipitación (( R )).
- Integrando la tasa en el tiempo, obtuvimos estimaciones de profundidad de lluvia acumulada.
- Visualizamos:
- Precipitación acumulada para 1 volumen
- Precipitación acumulada en 2 volúmenes consecutivos
- Precipitación total para el evento completo
- Marshall, J. S., & Palmer, W. M. K. (1948). THE DISTRIBUTION OF RAINDROPS WITH SIZE. Journal of Meteorology, 5(4), 165–166. https://doi.org/10.1175/1520-0469(1948)005<0165:tdorws>2.0.co;2