Skip to article frontmatterSkip to article content

Radares Meteorológicos

Radares Meteorológicos


🧭 Introducción

Este cuaderno enseña cómo acceder, procesar y visualizar datos de radares meteorológicos del IDEAM desde AWS.

📚 Descripción general

En este cuaderno aprenderás a acceder y procesar datos de radar meteorológico en Colombia. Explorarás cómo leer archivos en formato RAWDSX2 utilizando la biblioteca raw2zarr, convertir los datos a formatos cloud-nativos (Zarr), y realizar visualizaciones básicas de reflectividad y otros productos radar.

Los datos provienen de la red de radares del IDEAM (Instituto de Hidrología, Meteorología y Estudios Ambientales de Colombia), que monitorea la atmósfera en tiempo real para pronóstico de tiempo severo y estimación de precipitación.

✅ Requisitos Previos

Conceptos

Importancia

Notas

Introducción a Xarray

Necesario

Lectura de datos multidimensionales

Introducción a Py-Art

Necesario

Lectura de datos de radar

Introducción a Xradar

Necesario

Lectura de datos de radar

Introducción a Wradlib

Necesario

Lectura de datos de radar

Fundamentos de radar meteorológico

Útil

Fundamentos básicos en radares meteorológicos

Introducción a NetCDF

Útil

Entender la metadata de los datos

⏱️ Tiempo estimado de aprendizaje: 30 minutos
✍️ Formato: Interactivo. Ejecuta y modifica el código en cada celda.


Librerías

Importamos las librerías necesarias para este cuaderno.

# Librerías necesarias
import cartopy.crs as ccrs
import cartopy.feature as cfeature
import cmweather
import fsspec
import matplotlib.pyplot as plt
import pandas as pd
import xradar as xd
from cartopy import geodesic
from shapely.geometry import Point

1. 🌎 Red de Radares del IDEAM en AWS

Colombia cuenta con una red de radares meteorológicos operados por diferentes instituciones. El IDEAM publica datos de 4 radares en banda C mediante un bucket público en Amazon Web Services (AWS).

Radar

Ubicación

Banda

Alcance

Carimagua

Meta

C

~200 km

Guaviare

Guaviare

C

~200 km

Munchique

Cauca

C

~200 km

Barrancabermeja

Santander

C

~200 km

1.1 🗺️ Ubicación de radares del IDEAM

El siguiente mapa muestra la ubicación geográfica de los radares IDEAM disponibles en AWS:

# Cargar los datos
df_radares = pd.read_csv("../data/radar_locations.csv")

# Crear figura con proyección geográfica
fig, ax = plt.subplots(
    figsize=(8, 8),
    subplot_kw={"projection": ccrs.PlateCarree()},
    dpi=120
)

# Configurar mapa base
ax.set_extent([-85, -65, -5, 15])
ax.add_feature(cfeature.LAND, facecolor="whitesmoke")
ax.add_feature(cfeature.COASTLINE, linewidth=0.5)
ax.add_feature(cfeature.BORDERS, linestyle=":")
ax.gridlines(draw_labels=True, linestyle="--", linewidth=0.5)

# Dibujar cada radar
for _, row in df_radares.iterrows():
    lon, lat = row["lon"], row["lat"]
    name = row["Name"]
    color = row["color"]
    
    # Punto del radar
    ax.plot(lon, lat, "o", color=color, markersize=6)
    ax.text(lon + 0.3, lat, name, fontsize=8)

    # Determinar radio en km (IDIGER tiene menor alcance)
    radio_km = 40 if "IDIGER" in name.upper() else 200
    
    # Dibujar círculo geodésico
    circle = geodesic.Geodesic().circle(lon=lon, lat=lat, radius=radio_km * 1000, n_samples=100)
    ax.plot(*circle.T, color=color, linewidth=1, alpha=0.3)

ax.set_title("Red de radares meteorológicos de Colombia")
plt.tight_layout()
/home/runner/micromamba/envs/cdh-python/lib/python3.13/site-packages/cartopy/io/__init__.py:242: DownloadWarning: Downloading: https://naturalearth.s3.amazonaws.com/50m_physical/ne_50m_land.zip
  warnings.warn(f'Downloading: {url}', DownloadWarning)
/home/runner/micromamba/envs/cdh-python/lib/python3.13/site-packages/cartopy/io/__init__.py:242: DownloadWarning: Downloading: https://naturalearth.s3.amazonaws.com/50m_physical/ne_50m_coastline.zip
  warnings.warn(f'Downloading: {url}', DownloadWarning)
/home/runner/micromamba/envs/cdh-python/lib/python3.13/site-packages/cartopy/io/__init__.py:242: DownloadWarning: Downloading: https://naturalearth.s3.amazonaws.com/50m_cultural/ne_50m_admin_0_boundary_lines_land.zip
  warnings.warn(f'Downloading: {url}', DownloadWarning)
<Figure size 960x960 with 1 Axes>

2.2 📡 Radares meteorológicos del IDEAM disponibles en AWS

El Instituto de Hidrología, Meteorología y Estudios Ambientales (IDEAM) ha puesto a disposición pública los datos de sus radares meteorológicos mediante un repositorio en la nube de Amazon Web Services (AWS). Este repositorio facilita el acceso a información cruda de reflectividad y otros productos en formato propietario (SIGMET/IRIS), permitiendo su análisis mediante herramientas especializadas.

La estructura del bucket es la siguiente:

s3://s3-radaresideam/l2_data/YYYY/MM/DD/Radar_name/RRRAAMMDDTTTTTT.RAWXXXX 

Donde:

  • YYYY, MM, DD indican el año, mes y día del escaneo.

  • Radar_name es el nombre del radar (por ejemplo: Guaviare, Munchique, Barrancabermeja, Carimagua).

  • RRRAAMMDDTTTTTT.RAWXXXX es el nombre del archivo en formato SIGMET, compuesto por:

    • RRR: código del radar (ej. GUA para Guaviare)

    • AA: año en 2 dígitos

    • MM: mes

    • DD: día

    • TTTTTT: hora de adquisición (UTC)

    • RAWXXXX: identificador interno generado por el software IRIS

IDEAM actualmente dispone de archivos para sus radares principales desde aproximadamente 2018. Los datos están organizados por fecha, por lo que es necesario navegar dentro del bucket por año, mes y día para acceder a los archivos específicos.

!aws s3 ls --no-sign-request s3://s3-radaresideam/l2_data/2021/09/19/
                           PRE Guaviare/
                           PRE Munchique/

3. 📥 Acceso a los datos de radar usando Python

IDEAM publica los datos de sus radares meteorológicos en un bucket público de Amazon Web Services (AWS). Gracias a herramientas como fsspec y xradar, es posible explorar estos datos, filtrarlos por fecha y estación, y analizarlos sin necesidad de descargarlos manualmente desde la web.

3.1 🔎 Exploración de archivos disponibles en el bucket

Primero, se establece una conexión con el bucket S3 de IDEAM utilizando fsspec. Esto permite buscar archivos según una ruta de interés que incluye fecha y nombre del radar.

import fsspec

# Crear sistema de archivos con acceso anónimo
fs = fsspec.filesystem("s3", anon=True)

# Buscar archivos de radar disponibles en una fecha específica
files = sorted(fs.glob("s3-radaresideam/l2_data/2022/08/09/Carimagua/CAR22080919*"))
files[:5]  # Mostrar los primeros 5 archivos encontrados
['s3-radaresideam/l2_data/2022/08/09/Carimagua/CAR220809190003.RAWDSVV', 's3-radaresideam/l2_data/2022/08/09/Carimagua/CAR220809190315.RAWDSW0', 's3-radaresideam/l2_data/2022/08/09/Carimagua/CAR220809190401.RAWDSW3', 's3-radaresideam/l2_data/2022/08/09/Carimagua/CAR220809190505.RAWDSW8', 's3-radaresideam/l2_data/2022/08/09/Carimagua/CAR220809191003.RAWDSWM']

3.2 📡 Lectura de archivos mediante streaming

Una vez localizado un archivo de interés, podemos leerlo directamente desde AWS mediante streaming sin necesidad de descargarlo al sistema local. Utilizamos fsspec.open() para abrir el archivo en modo lectura y luego xradar lo lee directamente, retornando una estructura jerárquica del tipo DataTree que organiza los barridos (sweeps) contenidos en el archivo.

# Seleccionamos un archivo del bucket
filepath = f"s3://{files[7]}"

# Opciones de acceso a S3 (anónimo)
storage_options = {"anon": True}

# Abrimos el archivo en modo streaming y lo leemos con xradar
stream = fsspec.open(filepath, mode="rb", **storage_options).open()
radar = xd.io.open_iris_datatree(stream.read())

# Visualizamos el contenido del datatree
display(radar)
Loading...

📘 xradar utiliza xarray y devuelve una estructura tipo DataTree, que organiza jerárquicamente la información contenida en los archivos SIGMET/IRIS, incluyendo múltiples niveles de escaneo por elevación.

3.3 📊 Gráfico de reflectividad

Una vez cargado el archivo con xradar, podemos acceder a un barrido individual (por ejemplo, sweep_0) y visualizar la reflectividad horizontal (DBZH) utilizando la funcionalidad xarray.plot que se encuentra incorporada en xarray.

Este primer gráfico mostrará la reflectividad en coordenadas de azimut y rango, tal como fue registrada por el radar.

# Accedemos al primer barrido (elevación más baja)
sweep = radar["sweep_0"]

# Visualizamos la reflectividad horizontal (DBZH)
sweep["DBZH"].plot(cmap="ChaseSpectral", vmin=-10, vmax=60);
<Figure size 640x480 with 2 Axes>

🎯 Este tipo de visualización es útil para inspeccionar rápidamente los valores de reflectividad en coordenadas polares. La reflectividad se mide en decibelios Z (dBZ) y representa la intensidad de los retornos del radar.

3.4 🌐 Georreferenciación de datos de radar

Los datos de radar inicialmente se encuentran en coordenadas polares: azimuth (ángulo de rotación horizontal) y range (distancia radial). Para representar estos datos en un sistema de coordenadas cartesianas (x, y, z), es necesario aplicar un proceso de georreferenciación.

La librería xradar permite realizar este proceso fácilmente con el método .xradar.georeference().

# Aplicamos georreferenciación al datatree completo
radar = radar.xradar.georeference()

# Inspeccionamos el barrido ya georreferenciado
display(radar["sweep_0"])
Loading...

🌐 La georreferenciación agrega nuevas coordenadas físicas x, y y z que representan la ubicación espacial real del haz de radar sobre la superficie terrestre. Esto es esencial para graficar en mapas o combinar con otras fuentes geoespaciales.

3.5 🗺️ Visualización georreferenciada

Una vez que los datos han sido georreferenciados, podemos generar una visualización en coordenadas cartesianas usando las nuevas variables x e y. Esto permite observar la reflectividad del radar en el espacio físico real, facilitando su integración con mapas o capas geográficas.


# Graficamos la reflectividad horizontal usando coordenadas georreferenciadas
radar["sweep_0"]["DBZH"].plot(
    x="x",
    y="y",
    cmap="ChaseSpectral",
    vmin=-10,
    vmax=60
);
<Figure size 640x480 with 2 Axes>

🗺️ Esta visualización representa los datos del radar en un plano cartesiano, donde la ubicación espacial ya no depende de azimut y rango, sino de distancias en metros respecto al radar (coordenadas x, y).

3.6 🗺️ Visualización en sistema de coordenadas geográficas

Para representar los datos de reflectividad en un mapa geográfico, es necesario convertir el sistema de coordenadas cartesianas del radar a un sistema proyectado. Podemos obtener esta proyección directamente desde el objeto radar utilizando xradar.georeference.get_crs() y crear una proyección compatible con cartopy.

# Obtener el sistema de referencia proyectado desde el radar
proj_crs = xd.georeference.get_crs(radar["sweep_0"].ds)

# Crear una proyección de Cartopy usando ese CRS
cart_crs = ccrs.Projection(proj_crs)

🧭 Esta proyección permitirá superponer correctamente los datos del radar sobre mapas de costas, fronteras y otros elementos geográficos usando cartopy.

fig = plt.figure(figsize=(7, 7))
ax = fig.add_subplot(111, projection=ccrs.PlateCarree())
radar["sweep_0"]["DBZH"].plot(
    x="x",
    y="y",
    cmap="ChaseSpectral",
    transform=cart_crs,
    cbar_kwargs=dict(pad=0.075, shrink=0.75),
    vmin=-10,
    vmax=60,
)
ax.coastlines()
ax.gridlines(draw_labels=True, ls="--", lw=0.5);
/home/runner/micromamba/envs/cdh-python/lib/python3.13/site-packages/cartopy/mpl/geoaxes.py:1762: UserWarning: The input coordinates to pcolormesh are interpreted as cell centers, but are not monotonically increasing or decreasing. This may lead to incorrectly calculated cell edges, in which case, please supply explicit cell edges to pcolormesh.
  result = super().pcolormesh(*args, **kwargs)
/home/runner/micromamba/envs/cdh-python/lib/python3.13/site-packages/cartopy/io/__init__.py:242: DownloadWarning: Downloading: https://naturalearth.s3.amazonaws.com/10m_physical/ne_10m_coastline.zip
  warnings.warn(f'Downloading: {url}', DownloadWarning)
<Figure size 700x700 with 2 Axes>

🌐 Este gráfico muestra la reflectividad del radar proyectada sobre un sistema de coordenadas geográficas. Es útil para análisis meteorológico, estudios hidrológicos y validación con otras fuentes de datos espaciales.

4. 🌧️ Estimación de lluvia a partir de reflectividad

Una de las aplicaciones más comunes del radar meteorológico es la estimación de tasas de precipitación. Para ello se utiliza una relación empírica entre la reflectividad Z y la intensidad de lluvia R, conocida como relación Z–R.

Una de las formas más conocidas y utilizadas es la propuesta por Marshall & Gunn (1953):

Z=200R1.6Z = 200 \cdot R^{1.6}

Despejando para RR:

R=(Z200)1/1.6R = \left( \frac{Z}{200} \right)^{1/1.6}

A continuación, implementamos este procedimiento paso a paso para estimar la lluvia a partir de un barrido de reflectividad horizontal (DBZH):

# Reflectividad en unidades logarítmicas (dBZ)
ref_log = radar["sweep_0"]["DBZH"]

# Conversión a unidades lineales
ref_lin = 10 ** (ref_log / 10)

# Aplicación de la ecuación de Marshall & Gunn (1953)
rr = (1 / 200) ** (1 / 1.6) * ref_lin ** (1 / 1.6)

Ahora podemos visualizar el campo de lluvia generado

4.1 🗺️ Visualización del campo de lluvia

fig = plt.figure(figsize=(7, 7))
ax = fig.add_subplot(111, projection=ccrs.PlateCarree())
rr.plot(
    x="x",
    y="y",
    cmap="jet",
    transform=cart_crs,
    cbar_kwargs=dict(
        pad=0.075, shrink=0.75, label=r"$Intensidad \ de \ lluvia \ [mm hr^{-1}]$"
    ),
    vmin=0,
    vmax=50,
)
ax.set_title(r"$Estimado \ de \ lluvia$")
ax.coastlines()
ax.gridlines(draw_labels=True, ls="--", lw=0.5);
/home/runner/micromamba/envs/cdh-python/lib/python3.13/site-packages/cartopy/mpl/geoaxes.py:1762: UserWarning: The input coordinates to pcolormesh are interpreted as cell centers, but are not monotonically increasing or decreasing. This may lead to incorrectly calculated cell edges, in which case, please supply explicit cell edges to pcolormesh.
  result = super().pcolormesh(*args, **kwargs)
<Figure size 700x700 with 2 Axes>

🏋️ Práctica: Explora otro radar y fecha

Aplica lo aprendido consultando datos de un radar diferente.

Desafío:

  1. Elige otro radar IDEAM (Guaviare, Munchique, o Barrancabermeja)

  2. Selecciona una fecha diferente (2021-2023)

  3. Descarga, visualiza y estima precipitación

Pistas:

  • Usa fs.glob() con el patrón del radar elegido

  • Verifica que la fecha tenga datos disponibles

  • Recuerda georreferenciar antes de graficar en mapa

# Tu código aquí
# 1. Buscar archivos de otro radar
# mi_radar = "Guaviare"
# mi_fecha = "2022/03/15"
# files = sorted(fs.glob(f"s3-radaresideam/l2_data/{mi_fecha}/{mi_radar}/*"))

# 2. Descargar y leer
# ...

# 3. Visualizar y estimar lluvia
# ...

**Notas sobre la solución:**

- **Radar Guaviare**: Ubicado en el departamento del Guaviare, monitorea la región amazónica colombiana
- **Fecha seleccionada**: Marzo suele tener actividad convectiva en la región
- **Relación Z-R**: Marshall & Gunn (1953) es una relación general; para mejores resultados se pueden usar relaciones específicas por tipo de lluvia (convectiva, estratiforme, tropical)
- **Unidades**: La reflectividad viene en dBZ (logarítmica), pero la ecuación Z-R requiere Z en unidades lineales (mm⁶/m³)

💡 **Experimenta con**:
- Otros radares: `Munchique` (costa Pacífico), `Barrancabermeja` (Magdalena Medio)
- Diferentes fechas: busca eventos extremos reportados en noticias
- Otros barridos: prueba con `sweep_1`, `sweep_2` (elevaciones mayores)
- Umbrales de lluvia: identifica zonas con precipitación > 20 mm/h

✅ Resumen

¡Felicitaciones! Ahora puedes:

Acceder a datos de radar del IDEAM desde AWS S3

Leer archivos SIGMET usando xradar y fsspec

Georreferenciar datos de radar a coordenadas cartesianas

Visualizar reflectividad en mapas con cartopy

Estimar precipitación usando relaciones Z-R empíricas


🚀 ¿Qué sigue?

Ahora que dominas el acceso a datos de radar, puedes explorar:

  • [3.5. Estimación Cuantitativa de Precipitación (QPE)] - Técnicas avanzadas de estimación de lluvia

  • [3.4. Perfiles Cuasi-Verticales (QVP)] - Análisis de estructura vertical de tormentas

  • Aplicaciones hidrológicas - Integrar lluvia estimada por radar en modelos de caudal

Proyecto sugerido:

Descarga datos de un evento extremo en tu región y analiza:

  • Evolución temporal de la tormenta

  • Máximos de reflectividad y ubicación

  • Lluvia acumulada estimada

  • Comparación con estaciones pluviométricas

📚 Otros recursos

A continuación, se listan recursos clave y bibliografía utilizada en el desarrollo de este cuadernillo:

🧰 Herramientas y documentación

📘 Lecturas recomendadas

📄 Referencias bibliográficas

  • Grover, M., Sherman, Z., Sharma, M., Ladino, A., Camron, C., & Radar Cookbook Contributors. (2023). Radar Cookbook. Zenodo. Grover et al. (2023)

  • Rose, B. E. J., Kent, J., Tyle, K., Clyne, J., Banihirwe, A., Camron, D., Ford, R., Morley, J., Grover, M., et al. (2023). Pythia Foundations (Version v2023.05.01). Zenodo. Rose et al. (2023)

  • Marshall, J. S., & Palmer, W. M. (1948). The distribution of raindrops with size. J. Atmos. Sci., 5, 165–166. Marshall & Palmer (1948)

References
  1. Grover, M., Sherman, Z., Sharma, M., Ladino, A., Camron, C., & Radar Cookbook Contributors. (2023). Radar Cookbook. Zenodo. 10.5281/ZENODO.8075855
  2. Rose, B., Kent, J., Tyle, K., Clyne, Banihirwe, A., Camron, D., Ford, R., Morley, J., Grover, M., Eroglu, O., Paul, K., May, R., Lkailynncar, Irving, D., Uieda, L., Ojaybee, Blain, P., & Moon, Z. (2023). ProjectPythia/pythia-foundations: v2023.05.01. Zenodo. 10.5281/ZENODO.7884572
  3. 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