Introducción a los radares meteorológicos y xradar¶
📚 Descripción general¶
Al completar este cuadernillo serás capaz de:
Leer archivos de radar en distintos formatos (SIGMET, NetCDF, ODIM, etc.)
Visualizar datos de reflectividad y otras variables polarimétricas
Georreferenciar datos para crear mapas con coordenadas reales
Aplicar filtros y seleccionar datos por rangos, azimut o elevación
Comparar el flujo de trabajo entre Py-ART, Xradar y Wradlib
Utilizar objetos
xarray.DataArray,Dataset, yDataTreepara datos de radar
✅ Requisitos previos¶
| Concepto | Importancia | Notas |
|---|---|---|
| NumPy | Necesario | Estructuras y operaciones con arrays |
| Xarray | Necesario | Acceso por coordenadas, etiquetado, .plot() |
| Matplotlib | Necesario | Generación de figuras |
| Cartopy | Útil | Visualización geográfica (opcional) |
| cmweather | Útil | Paletas de colores meteorológicas |
| Radar Cookbook | Sugerido | Casos de uso adicionales |
⏱️ Tiempo estimado de aprendizaje:
📖 Solo lectura: 45–60 minutos
🏋️ Con actividades prácticas: 90–120 minutos
✍️ Formato: interactivo, ejecuta y modifica el código a medida que avanzas
1. Introducción¶
En este cuadernillo aprenderás a trabajar con datos de radares meteorológicos usando la librería xradar.
Xradar es una herramienta moderna y de código abierto, diseñada para importar, estructurar y preparar datos de radar para análisis científico utilizando el ecosistema de Python — en particular xarray.
📦 ¿Qué hace Xradar?
Lee múltiples formatos de radar (e.g. SIGMET, ODIM_H5, Cf/Radial, Rainbow, NEXRAD).
Organiza los datos en un modelo jerárquico compatible con el estándar WMO FM301 / CfRadial2.1.
Permite el acceso estructurado y el análisis directo de múltiples variables radar como
Z,ZDR,VEL, entre otras.Facilita la visualización y análisis de grandes volúmenes de datos usando herramientas como
matplotlib,cartopyodask.
Este módulo está pensado como punto de entrada al análisis de radar meteorológico basado en etiquetas, coordenadas geográficas y estándares abiertos.
Librerías¶
Comencemos importando las librerías necesarias para este cuadernillo:
import xradar as xd # Lectura y manipulación de datos radar
import xarray as xr # Estructuras de datos multidimensionales
import numpy as np # Operaciones numéricas
import matplotlib.pyplot as plt # Visualización
import cmweather # Paletas de colores meteorológicas (ChaseSpectral, etc.)2. ¿Cómo funcionan los radares meteorológicos? 🎬¶
Antes de explorar xradar es útil entender cómo opera un radar meteorológico.
A continuación te presentamos un video explicativo sobre el proceso de escaneo volumétrico que realiza un radar:
Operación de un radar meteorológico. Fuente:UCAR
🌀 ¿Qué estás viendo?¶
El radar gira 360° a una altura fija, recolectando datos como reflectividad — útiles para visualizar la precipitación.
Luego se inclina a un ángulo más alto y repite el proceso.
Estas múltiples barridas crean un patrón volumétrico llamado Patrón de Cobertura de Volumen (VCP) con forma de dona 🍩.
Este ciclo se repite cada pocos minutos, permitiendo realizar análisis en series de tiempo y seguimiento de tormentas.
🎓 Este contexto es clave para entender cómo procesar e interpretar los datos en las siguientes secciones.
3.1. 🤝 Contexto y propósito de Xradar¶
Xradar nació como una iniciativa de colaboración comunitaria para unificar el acceso a datos de radar meteorológico en Python.
¿Por qué Xradar?
📖 Lectura unificada: Soporta múltiples formatos (SIGMET, Rainbow, NEXRAD, ODIM_H5, etc.)
🌐 Estándar abierto: Implementa CfRadial 2.1 / FM301 de la WMO
🔗 Interoperabilidad: Compatible con Py-ART, Wradlib, y todo el ecosistema xarray
☁️ Optimizado para la nube: Diseñado para ARCO (Analysis-Ready Cloud-Optimized)
📚 Contexto histórico: ERAD 2022
Durante la conferencia ERAD 2022 (European Conference on Radar in Meteorology and Hydrology) en Locarno, Suiza, desarrolladores de múltiples paquetes (Py-ART, Wradlib, Baltrad, etc.) llegaron a un consenso:
🧩 Para maximizar la colaboración y facilitar el trabajo de la comunidad, se necesitaba una librería única y centralizada dedicada a leer e interpretar datos de radar.
Así nació Xradar, con el objetivo de:
Leer múltiples formatos de radar y exportarlos en estándares reconocidos
Utilizar
xarraycomo modelo de memoria siguiendo CfRadial 2.1 / FM301Permitir que cualquier herramienta que trabaje con
xarraypueda leer, manipular y escribir datos de forma interoperable y escalable
🧠 En resumen: Xradar es el punto de entrada unificado para el procesamiento moderno de datos de radar.
Enlaces útiles:
3.2 Lectura de datos con open_iris_datatree 📂¶
Xradar utiliza la función open_iris_datatree para cargar archivos en formato SIGMET/IRIS dentro de un modelo de árbol jerárquico (xarray.DataTree). Cada volumen de elevación (sweep) se convierte en un nodo hijo, lo que permite navegar fácilmente entre escaneos.
🔍 Este enfoque facilita la visualización, selección y análisis de datos individuales por barrido (elevación).
import xradar as xd
# Ruta del archivo SIGMET
archivo = "../data/CAR220809191504.RAWDSX2"
# Lectura del archivo usando Xradar
radar_xd = xd.io.open_iris_datatree(archivo)
radar_xd📘 ¿Soporta otros formatos además de SIGMET/IRIS?¶
¡Sí! Xradar es compatible con múltiples formatos de radar como ODIM_H5, CfRadial1/2, Rainbow, NEXRAD Level II, entre otros.
Para ver una lista completa de formatos soportados y sus respectivas funciones de carga, consulta la documentación oficial aquí: 🔗 Xradar Importers — Documentación Oficial
3.3 🧬 Modelo de datos jerárquico CfRadial2.1/FM301¶
Aprovechando la estructura jerárquica basada en el formato Climate and Forecast (CF), descrita por el estándar FM301 y respaldada por la Organización Meteorológica Mundial (WMO), se desarrolló un modelo de datos abierto y eficiente para organizar, gestionar y almacenar datos de radar en la nube. Este enfoque está alineado con los principios de Analysis-Ready Cloud-Optimized (ARCO), facilitando el acceso e interoperabilidad.
🌐 Estándar CfRadial2.1/FM301¶
Xradar utiliza objetos de tipo xarray.DataTree para organizar los barridos del radar dentro de una estructura jerárquica. Cada barrido (sweep) se representa como un xarray.Dataset que contiene tanto los datos científicos como sus metadatos y coordenadas asociadas.
📷 A continuación se muestra una representación gráfica del modelo jerárquico FM301/CfRadial2.1:
Figure 2:Diagrama del modelo jerárquico CfRadial2.1/FM301 utilizado por Xradar.
Este diseño permite:
Acceso ordenado a múltiples barridos (elevaciones) dentro de un solo volumen
Compatibilidad con formatos estandarizados y optimizados para la nube
Interoperabilidad con otras librerías como
pyart,wradlib, y herramientas de análisis geoespacial
3.4 Exploración del DataTree y estructura de barridos 🧭¶
Una vez que cargamos nuestros datos radar con xradar, obtenemos un objeto tipo xarray.DataTree, que representa una estructura jerárquica del volumen radar. Cada barrido (sweep) se representa como un grupo hijo y contiene un conjunto de datos (xarray.Dataset) con variables científicas, coordenadas y atributos relevantes.
🔎 Esta estructura nos permite navegar y acceder a diferentes componentes del volumen de radar de manera ordenada y legible.
📁 Nivel raíz (/)¶
En el nivel raíz (/) se encuentran los atributos globales del volumen de radar, se muestra a continuación:
radar_xd["/"].ds🌪️ Nivel de barridos individuales (/sweep_0, /sweep_1, …)¶
Cada grupo /sweep_i representa un barrido a un ángulo de elevación específico. Aquí se encuentra la mayor parte de los datos científicos:
sweep0 = radar_xd["sweep_0"]
sweep0Esto nos devuelve un nuevo nodo del árbol (DataTree) y no directamente el set de datos (Dataset).
sweep0_dataset = radar_xd["sweep_0"].ds
sweep0_dataset📡 Nivel de Variables individuales (DBZH, RHOHV, …)¶
En el nivel más profundo del modelo jerárquico de Xradar (también llamado nivel hoja del árbol DataTree), encontramos las variables científicas individuales contenidas en cada barrido (sweep).
Estas variables incluyen productos como:
DBZH: Reflectividad horizontalZDR: Reflectividad diferencialRHOHV: Correlación cruzadaKDP: Gradiente de fase diferencialVRADH: Velocidad radialWRADH: Ancho espectral
radar_xd["sweep_0/DBZH"]Estas variables contienen los valores físicos medidos por el radar y están organizadas sobre las dimensiones:
azimuth: direcciones del haz de radar (ej. 0° a 360°)range: distancias radiales desde el radar (en metros)
🧾 Metadatos CF-Compliant (attrs):
Cada variable posee atributos normalizados bajo las convenciones CF (Climate and Forecast) que facilitan la interoperabilidad:
standard_name: radar_equivalent_reflectivity_factor_h
units: dBZ
long_name: Equivalent reflectivity factor H🏋️ Práctica 1: Exploración básica de datos radar¶
Usando el objeto radar_xd que cargamos, responde las siguientes preguntas:
Tareas:
¿Cuántos sweeps (barridos) hay en este volumen radar?
¿Cuál es el ángulo de elevación del
sweep_0?¿Cuántos rayos (azimuth) y cuántas puertas de rango (range) tiene el
sweep_0?Lista todas las variables disponibles en el
sweep_0
# Tu código aquíSolución
# 1. Número de sweeps
print(f"Número de sweeps: {len([k for k in radar_xd.groups if 'sweep' in k])}")
# 2. Ángulo de elevación del sweep_0
elevacion = radar_xd["sweep_0"].ds.sweep_fixed_angle.values
print(f"Ángulo de elevación: {elevacion}°")
# 3. Dimensiones (azimuth y range)
dims = radar_xd["sweep_0"].ds.dims
print(f"Azimuth: {dims['azimuth']} rayos")
print(f"Range: {dims['range']} puertas")
# 4. Variables disponibles
variables = list(radar_xd["sweep_0"].ds.data_vars)
print(f"Variables: {variables}")3.5 🎨 Visualización de variables radar¶
Una de las ventajas de trabajar con xarray es su capacidad de generar visualizaciones de manera sencilla usando el método .plot(), sin necesidad de configurar manualmente matplotlib.
📐 Visualización en coordenadas nativas (azimuth, range)¶
En el caso de datos de radar, podemos visualizar variables como la reflectividad (DBZH) directamente desde un DataArray. Sin embargo, por defecto los datos están organizados en coordenadas rectangulares (azimuth, range), no polares ni geográficas.
# importamos cmweather para acceder a la paleta "ChaseSpectral"\
import cmweather
# Visualizar reflectividad en coordenadas nativas (azimuth, range)
radar_xd["sweep_0"]["DBZH"].plot(cmap="ChaseSpectral", vmin=-10, vmax=60);
Este gráfico muestra los datos en una cuadrícula rectangular, con azimuth en el eje vertical y range en el eje horizontal.
No representa una vista polar ni georreferenciada.
🌍 Visualización georreferenciada (x, y, z)¶
Para obtener una vista espacial, primero aplicamos georreferenciación al volumen usando:
# Georreferenciar: convertir coordenadas polares (azimuth, range)
# a coordenadas cartesianas (x, y, z) en metros desde el radar
# Esto permite visualizar los datos en un plano espacial real
radar_geo = radar_xd.xradar.georeference()
radar_geo["sweep_0"]Esto agrega coordenadas espaciales (x, y y z) a los datos, permitiendo representarlos en un plano cartesiano relativo a la posición del radar.
# Visualización georreferenciada usando coordenadas x, y
# x, y: distancias en metros desde la ubicación del radar
# Esto produce una vista más intuitiva del campo de reflectividad
radar_geo["sweep_0"]["DBZH"].plot(x="x",y="y",cmap="ChaseSpectral",vmin=-10,vmax=60);
Ahora sí obtenemos una vista más representativa de la escena observada por el radar, ideal para análisis geoespaciales.
3.6 ✂️ Selección de datos (Slicing)¶
Una vez que tenemos los datos georreferenciados, podemos aprovechar las coordenadas para seleccionar subconjuntos específicos, por ejemplo:
Un rango de ángulos (
azimuth)Una distancia determinada (
range)O incluso combinaciones de ambas
Esto es útil para enfocar el análisis en una región particular del barrido de radar.
🔍 Selección por rango de ángulos¶
Supongamos que queremos visualizar los datos entre 40° y 120° de azimuth:
# Seleccionar un sector específico de azimuth (30° a 120°)
# azimuth: ángulo horizontal desde el norte (0° = norte, 90° = este)
# Útil para enfocar análisis en una región específica del escaneo
radar_geo["sweep_0"]["DBZH"].sel(azimuth=slice(30, 120)).plot(x="x",y="y",cmap="ChaseSpectral",vmin=-10,vmax=60);
📏 Selección por distancia (range)¶
También podemos limitar la visualización a una distancia máxima, por ejemplo, los primeros 100 km desde el radar:
# Limitar visualización a los primeros 100 km desde el radar
# range: distancia radial desde el radar en metros# Primeros 100 km suelen tener mejor calidad de datos
radar_geo["sweep_0"]["DBZH"].sel(range=slice(0, 100_000)).plot(x="x",y="y",cmap="ChaseSpectral",vmin=-10, vmax=60);
🔍 Selección combinada de azimuth y range¶
Las selecciones se pueden combinar fácilmente. Por ejemplo, un sector de 20° a 120° de azimuth y un rango de 25 hasta 50 km:
# Selección combinada: sector específico de azimuth Y rango
# 20-120° azimuth, 25-50 km de distancia# Permite analizar subregiones específicas del volumen radar
radar_geo["sweep_0"]["DBZH"].sel(
azimuth=slice(20, 120),
range=slice(25_000, 50_000)).plot(x="x",
y="y",
cmap="ChaseSpectral",
vmin=-10,
vmax=60
);
Estas herramientas de slicing te permiten reducir el volumen de datos visualizado o analizado, y son especialmente útiles para estudios de casos puntuales o fenómenos meteorológicos localizados.
📡 Corte radial en un solo azimuth¶
También podemos visualizar cómo varía la reflectividad a lo largo del rango para un solo valor de azimuth. Esto permite observar el perfil horizontal de reflectividad en una dirección específica:
# Extraer perfil radial en un solo azimuth (55°)
# Muestra cómo varía la reflectividad con la distancia en una dirección fija
# method="nearest": encuentra el rayo más cercano a 55°
radar_xd["sweep_0"]["DBZH"].sel(azimuth=55, method="nearest").plot();
🏋️ Práctica 2: Visualización y selección de datos¶
Ahora que sabes georreferenciar y seleccionar datos, practica con estos ejercicios:
Tareas:
Visualiza la reflectividad (DBZH) solo para el sector entre 90° y 180° de azimut
Crea un gráfico de la velocidad radial (VRADH) limitado a los primeros 50 km de rango
Extrae y grafica un perfil radial de reflectividad a 270° de azimut
Desafío: Encuentra el rango y azimut donde se encuentra el máximo de reflectividad
# Tu código aquíSolución
# 1. Sector 90-180° azimut
radar_geo["sweep_0"]["DBZH"].sel(azimuth=slice(90, 180)).plot(
x="x", y="y", cmap="ChaseSpectral", vmin=-10, vmax=60
)
plt.title("Reflectividad 90-180° azimut")
# 2. Primeros 50 km
radar_geo["sweep_0"]["VRADH"].sel(range=slice(0, 50_000)).plot(
x="x", y="y", cmap="twilight_shifted", vmin=-30, vmax=30
)
plt.title("Velocidad radial (50 km)")
# 3. Perfil radial a 270°
radar_xd["sweep_0"]["DBZH"].sel(azimuth=270, method="nearest").plot()
plt.title("Perfil radial a 270°")
# 4. Máximo de reflectividad
dbzh = radar_xd["sweep_0"]["DBZH"]
max_val = dbzh.max().values
max_loc = dbzh.where(dbzh == dbzh.max(), drop=True)
print(f"Reflectividad máxima: {max_val:.1f} dBZ")
print(f"Azimut: {float(max_loc.azimuth.values):.1f}°")
print(f"Rango: {float(max_loc.range.values):.0f} m")3.6 Acceso y visualización de variables polarimétricas 🌈¶
Además de la reflectividad (DBZH), los radares polarimétricos generan otras variables que nos permiten obtener más información sobre el tipo de precipitación, el tamaño de las gotas, o la presencia de granizo.
🎨 Reflectividad Diferencial (ZDR)¶
ZDR compara la señal horizontal vs. vertical del radar. Valores positivos indican gotas achatadas (lluvia), mientras que valores cercanos a cero o negativos pueden estar asociados con granizo o nieve.
# Visualización de Reflectividad Diferencial (ZDR)
# ZDR compara señal horizontal vs vertical
radar_xd["sweep_0"]["ZDR"].plot(
x="x",
y="y",
cmap="jet",
vmin=-1,
vmax=5,);
💨 Velocidad radial (VRADH)¶
VRADH representa la componente del viento en dirección del haz del radar. Los valores negativos indican acercamiento hacia el radar, y positivos, alejamiento. Este producto es clave para estimar flujos de viento, vórtices o firmas de tornados.
# Visualización de Velocidad Radial (VRADH)# VRADH: componente del viento hacia/desde el radar
radar_xd["sweep_0"]["VRADH"].plot(
x="x", y="y",
cmap="twilight_shifted",
vmin=-10, vmax=10,);
🏋️ Práctica 3: Interpretación de variables polarimétricas¶
Las variables polarimétricas nos dan información sobre el tipo de hidrometeoros. Practica interpretando estos datos:
Tareas:
Visualiza ZDR solo para valores donde DBZH > 20 dBZ (usa
.where())Calcula el promedio espacial de RHOHV (sobre azimuth y range)
Identifica regiones con ZDR > 2 dB - ¿qué tipo de hidrometeoros sugiere?
Aplicación: Compara DBZH y ZDR en la misma región - ¿qué diferencias observas?
# Tu código aquíSolución
# 1. ZDR donde DBZH > 20
dbzh_mask = radar_xd["sweep_0"]["DBZH"] > 20
zdr_filtered = radar_xd["sweep_0"]["ZDR"].where(dbzh_mask)
zdr_filtered.plot(x="x", y="y", cmap="jet", vmin=-1, vmax=5)
plt.title("ZDR donde DBZH > 20 dBZ")
# 2. Promedio espacial de RHOHV
rhohv_mean = radar_xd["sweep_0"]["RHOHV"].mean(dim=["azimuth", "range"])
print(f"RHOHV promedio: {rhohv_mean.values:.3f}")
# 3. Regiones con ZDR > 2 dB
zdr_high = radar_xd["sweep_0"]["ZDR"] > 2
print("Regiones con ZDR > 2 dB indican posibles gotas grandes de lluvia o granizo pequeño")
# 4. Comparación DBZH vs ZDR
fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(12, 4))
radar_geo["sweep_0"]["DBZH"].plot(x="x", y="y", cmap="ChaseSpectral",
vmin=-10, vmax=60, ax=ax1)
ax1.set_title("Reflectividad (DBZH)")
radar_geo["sweep_0"]["ZDR"].plot(x="x", y="y", cmap="jet",
vmin=-1, vmax=5, ax=ax2)
ax2.set_title("Reflectividad Diferencial (ZDR)")
plt.tight_layout()
print("""\nInterpretación:
- DBZH muestra la intensidad del retorno del radar
- ZDR muestra la forma de las partículas (oblatas vs esféricas)
- Valores altos de ZDR con DBZH moderado pueden indicar lluvia intensa con gotas grandes
""")✅ Conclusiones¶
En este cuadernillo exploramos el uso de Xradar, una librería clave en el ecosistema de ciencia abierta para datos de radar meteorológico.
🔍 A lo largo del módulo, aprendiste a:
Leer datos en formato SIGMET/IRIS usando
open_iris_datatree.Explorar la estructura jerárquica
xarray.DataTreecompatible con el modelo FM301/CfRadial2.1.Acceder a variables individuales (
DBZH,ZDR,VRADH, etc.) y sus metadatos.Visualizar datos radar de forma rápida, tanto en coordenadas de radar como en coordenadas georreferenciadas.
Realizar slicing y filtrado de datos usando coordenadas físicas (
azimuth,range,x,y).Interpretar variables polarimétricas para análisis de hidrometeoros.
📘 ¿Qué sigue?
Ahora que dominas el uso de Xradar como punto de entrada, puedes explorar:
Formatos ARCO (Analysis-Ready Cloud-Optimized): Zarr, Kerchunk para datos en la nube
Py-ART: procesamiento avanzado, correcciones y análisis estadísticoWradlib: procesamiento físico, filtrado y estimación cuantitativa de precipitaciónRadar Cookbook: casos de uso avanzados con Py-ARTHerramientas geoespaciales como
cartopyygeopandaspara mapas y análisis geográficos
🛰️ Xradar te ofrece una base sólida y reproducible para el análisis moderno de radar meteorológico.
- Grover, M., Sherman, Z., Sharma, M., Ladino, A., Camron, C., & Radar Cookbook Contributors. (2023). Radar Cookbook. Zenodo. 10.5281/ZENODO.8075855