
Estaciones hidrometeorológicas¶
Introducción¶
En este cuadernillo (Notebook) aprenderemos:
- Introduccion a la red de monitoreo del IDEAM
- Cátalogo de estaciones de IDEAM
- Consulta de datos usando la plataforma datosabiertos
.gov .co - Consulta de datos de temperatura y precipitación
- Otros datos disponibles
Prerequisitos¶
Conceptos | Importancia | Notas |
---|---|---|
Introducción a Pandas | Necesario | Lectura de datos tabulares |
Introducción a Datetime | Necesario | Entender estampas de tiempo |
Introducción a Cartopy | Necesario | Entender estampas de tiempo |
Introducción a folium | Útil | Mapas interactivos |
- Tiempo de aprendizaje: 30 minutos
1. Catálogo nacional de estaciones de IDEAM¶
Según el catálogo de estaciones hidrometeorológicas del IDEAM, el país cuenta con alrededor de 4.400 estaciones de diferentes categorías. En el siguiente cuadro se resume el estado de las estaciones por categoría de acuerdo a la PQR No. 20229050190832 (Enero de 2023)
Categoría | Activa | Mantenimiento | Suspendidas |
---|---|---|---|
Limnográfica | 287 | 109 | 106 |
Climátologica principal | 215 | 60 | 92 |
Mareográfica | 4 | 2 | 2 |
Pluviográfica | 104 | 0 | 87 |
Limnométrica | 323 | 11 | 557 |
Climática Ordinaria | 211 | 31 | 253 |
Agrometeorológica | 51 | 4 | 57 |
Radio Sonda | 6 | 2 | 2 |
Pluviométrica | 1109 | 9 | 603 |
Meteorológica Especial | 40 | 4 | 68 |
Sinóptica Principal | 27 | 3 | 4 |
Sinóptica Secundaria | 2 | 0 | 5 |
Total | 2381 | 235 | 1866 |
Librerías¶
A continuación vamos a importar las librerías que utilizaremos en este cuadernillo.
from datetime import datetime, timedelta
import cartopy.crs as ccrs
import cartopy.feature as feature
import matplotlib.pyplot as plt
import pandas as pd
from matplotlib.dates import DateFormatter, HourLocator
from pandas import to_datetime
from sodapy import Socrata
2. Acceso al catálogo en bart.ideam.gov.co¶
El catálogo nacional de estaciones del IDEAM actualizado se encuentra disponible en el servidor Bart. Podemos leer el catálogo usando pandas.read_excel
como se muestra a continuación:
client = Socrata("www.datos.gov.co", None)
results = client.get("hp9r-jxuu", limit=10000)
# Convert to pandas DataFrame
df_cat = pd.DataFrame.from_records(results)
WARNING:root:Requests made without an app_token will be subject to strict throttling limits.
df_cat["latitud"] = df_cat["ubicaci_n"].apply(lambda d: float(d["latitude"]))
df_cat["longitud"] = df_cat["ubicaci_n"].apply(lambda d: float(d["longitude"]))
df_cat.head()
df_cat["estado"].str.lower()
0 activa
1 activa
2 activa
3 activa
4 activa
...
8968 activa
8969 activa
8970 activa
8971 activa
8972 activa
Name: estado, Length: 8973, dtype: object
filtered_df = df_cat[
(df_cat["entidad"].str.lower() == "ideam") &
(df_cat["estado"].str.lower() == "activa")
]
filtered_df
2.1 Mapa de estaciones¶
Podemos usar cartopy
para hacer un mapa y visualizar las estaciones de monitoreo en el país
fig, ax = plt.subplots(subplot_kw={"projection": ccrs.PlateCarree()}, dpi=150)
ax.coastlines()
gl = ax.gridlines(draw_labels=True, crs=ccrs.PlateCarree())
ax.scatter(df_cat["longitud"], df_cat["latitud"], transform=ccrs.PlateCarree(), s=0.5)
ax.add_feature(feature.LAND)
ax.add_feature(feature.OCEAN)
ax.add_feature(feature.COASTLINE, linewidth=0.5)
ax.add_feature(feature.BORDERS, linewidth=0.5)
<cartopy.mpl.feature_artist.FeatureArtist at 0x7f79764220c0>
/home/runner/micromamba/envs/cdh-python/lib/python3.12/site-packages/cartopy/io/__init__.py:241: 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.12/site-packages/cartopy/io/__init__.py:241: DownloadWarning: Downloading: https://naturalearth.s3.amazonaws.com/50m_physical/ne_50m_ocean.zip
warnings.warn(f'Downloading: {url}', DownloadWarning)
/home/runner/micromamba/envs/cdh-python/lib/python3.12/site-packages/cartopy/io/__init__.py:241: 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.12/site-packages/cartopy/io/__init__.py:241: DownloadWarning: Downloading: https://naturalearth.s3.amazonaws.com/50m_cultural/ne_50m_admin_0_boundary_lines_land.zip
warnings.warn(f'Downloading: {url}', DownloadWarning)

podemos agrupar la data por área operativa, tipo de estación, tecnología, y otras variables
df_grp = df_cat.groupby("estado")
fig, ax = plt.subplots(subplot_kw={"projection": ccrs.PlateCarree()}, dpi=150)
for _, group in df_grp:
ax.scatter(
group["longitud"],
group["latitud"],
transform=ccrs.PlateCarree(),
s=0.5,
label=_,
)
ax.coastlines()
gl = ax.gridlines(draw_labels=True, crs=ccrs.PlateCarree())
ax.add_feature(feature.LAND)
ax.add_feature(feature.OCEAN)
ax.add_feature(feature.COASTLINE, linewidth=0.5)
ax.add_feature(feature.BORDERS, linewidth=0.5)
ax.legend(fontsize=5)

# df_grp = df_cat.groupby("entidad")
# fig, ax = plt.subplots(subplot_kw={"projection": ccrs.PlateCarree()}, dpi=150)
# for _, group in df_grp:
# ax.scatter(
# group["longitud"],
# group["latitud"],
# transform=ccrs.PlateCarree(),
# s=0.5,
# label=_,
# )
# ax.coastlines()
# gl = ax.gridlines(draw_labels=True, crs=ccrs.PlateCarree())
# ax.add_feature(feature.LAND)
# ax.add_feature(feature.OCEAN)
# ax.add_feature(feature.COASTLINE, linewidth=0.5)
# ax.add_feature(feature.BORDERS, linewidth=0.5)
# ax.legend(fontsize=5)
Podemos validar el número total de estaciones activas, en matenimiento y suspendidas de acuerdo con la información contenida en el catálogo
for grp in df_grp.groups.keys():
print(f"{grp}: {len(df_grp.get_group(grp))}")
Activa: 5491
En Mantenimiento: 43
Suspendida: 3439
2.2 Mapa de estaciones interactivo¶
También podemos hacer mapas interactivos usando folium
import folium
from folium import plugins
from folium.plugins import MarkerCluster
min_lon, max_lon, min_lat, max_lat = -90, -72, -1, 14
map_ = folium.Map(
location=[8, -76],
zoom_start=6,
min_lat=min_lat,
max_lat=max_lat,
min_lon=min_lon,
max_lon=max_lon,
zoom_control=False,
control_scale=True,
scrollWheelZoom=True,
width=1000,
height=600,
)
marker_cluster = MarkerCluster(name="Estaciones").add_to(map_)
folium.TileLayer("cartodbpositron").add_to(map_)
folium.TileLayer("openstreetmap").add_to(map_)
folium.TileLayer("cartodbdark_matter").add_to(map_)
folium.LayerControl().add_to(map_)
minimap = plugins.MiniMap()
_ = map_.add_child(minimap)
Ahora agregamos las estaciones usando la siguiente función:
def plot_station(row):
"""input: series that contains a numeric named latitude and a numeric named longitude
this function creates a CircleMarker and adds it to your this_map"""
html = row.to_frame("_").to_html(
classes="table table-striped table-hover table-condensed table-responsive"
)
popup = folium.Popup(html, max_width=2650)
folium.Marker(location=[row.latitud, row.longitud], popup=popup).add_to(
marker_cluster
)
df_cat.apply(plot_station, axis=1)
map_
3. Acceso a la información histórica de IDEAM usando datosabiertos .gov .co¶
la información histórica de múltiples sensores se puede consultar a través de la plataforma de datos abiertos usando el aplicativo sodapy. Socrata utiliza un módulo denominado Socrata
que permite realizar consultas al repositorio. Cada variable hidrometeorógica dispuesta se puede consultar usando el su respectivo código del set de datos.
Variable | Código del set de datos |
---|---|
Dirección del viento | kiw7-v9ta |
Nivel instantáneo | bdmn-sqnh |
Temperatura Mínima del Aire | afdg-3zpb |
Temperatura Máxima del Aire | ccvq-rp9s |
Velocidad del Viento | sgfv-3yp8 |
Nivel Máximo | vfth-yucv |
Nivel Mínimo | pt9a-aamx |
Humedad del Aire | uext-mhny |
Temperatura | sbwg-7ju4 |
Nivel del mar mínimo | 7z6g-yx9q |
Nivel del mar máximo | uxy3-jchf |
Nivel del mar | ia8x-22em |
Presión Atmosferica | 62tk-nxj5 |
Precipitación | s54a-sgyg |
3.1 Precipitación (s54a-sgyg)¶
Vamos a consultar los datos de precipitación
reportada en la página, por ende vamos a usar el código s54a-sgyg
. Para esto usamos el método Socrata
, pasamos la dirección del repositorio y None
que corresponde a la no autenticación
# conexión cliente usando socrata al repositorio de datos abiertos
client = Socrata("www.datos.gov.co", None)
WARNING:root:Requests made without an app_token will be subject to strict throttling limits.
Una vez creado el cliente empezamos a hacer la consulta de datos usando client.get
y pasando los respectivos parámetros dataset_identifier
, de la tabla anterior , y limit
para generar consultas no muy grandes para efectos demostrativos. El resultado es una lista con múltiples diccionarios como se puede ver a continuación.
# Solicitud de informacion al repositorio de interés
results = client.get(dataset_identifier="s54a-sgyg", limit=2000)
results[:1]
[{'codigoestacion': '0023195230',
'codigosensor': '0240',
'fechaobservacion': '2023-09-20T13:10:00.000',
'valorobservado': '0',
'nombreestacion': 'NEOMUNDO',
'departamento': 'SANTANDER',
'municipio': 'BUCARAMANGA',
'zonahidrografica': 'MEDIO MAGDALENA',
'latitud': '7.09999722',
'longitud': '-73.11',
'descripcionsensor': 'PRECIPITACIÓN',
'unidadmedida': 'mm'}]
Estos resultados los podemos convertir en un Dataframe
usando pandas
results_df = pd.DataFrame.from_records(results)
results_df.head()
Ahora podemos usar filtrar los datos por diferentes campos como el codigoestacion
, fechaobservacion
, o valorobservado
. Podemos pasar parámetros SQL
como where
, AND
, IN
, entre otros, en el método client.get
# client.get?
# Solicitud de informacion para la estación de la Universidad Nacional - Bogotá - 0021205012
ppt_query = client.get(
dataset_identifier="s54a-sgyg",
select="fechaobservacion, valorobservado, codigoestacion",
where="codigoestacion IN ('0021205012') \
AND fechaobservacion > '2017'",
)
df_est = pd.DataFrame.from_records(ppt_query)
df_est.head()
Gráfico de la serie temporal¶
Podemos generar una serie temporal usando la información resultado de la consulta. Sin embargo, primero debemos revisar el tipo de dato de cada columna
df_est.info()
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 1000 entries, 0 to 999
Data columns (total 3 columns):
# Column Non-Null Count Dtype
--- ------ -------------- -----
0 fechaobservacion 1000 non-null object
1 valorobservado 1000 non-null object
2 codigoestacion 1000 non-null object
dtypes: object(3)
memory usage: 23.6+ KB
df_est["fechaobservacion"] = pd.to_datetime(df_est["fechaobservacion"])
df_est.set_index("fechaobservacion", inplace=True)
df_est.valorobservado = df_est["valorobservado"].astype(float)
df_est = df_est.sort_index()
df_est.tail()
# pd.options.plotting.backend = 'holoviews'
fig, ax = plt.subplots(figsize=(12, 3))
df_est["valorobservado"].plot(ax=ax, drawstyle="steps")
<Axes: xlabel='fechaobservacion'>

Podemos solicitar información para estaciones que reportan datos en el último mes
ppt_query = client.get(
dataset_identifier="s54a-sgyg",
select="fechaobservacion, valorobservado, codigoestacion, nombreestacion",
where="fechaobservacion > '2023-09-11'",
)
df_ult = pd.DataFrame.from_records(ppt_query)
df_ult.head()
3.2 Temperatura (sbwg-7ju4)¶
De manera similar podemos consultar otros registros como los de temperatura. Cambiamos el identificador de set de datos y generamos una nueva consulta
# Solicitud de informacion para la estación de la Universidad Nacional - Bogotá - 0021205012
temp_query = client.get(
dataset_identifier="sbwg-7ju4",
select="fechaobservacion, valorobservado, codigoestacion",
where="codigoestacion IN ('0021205012') \
AND fechaobservacion > '2020'",
)
df_temp = pd.DataFrame.from_records(temp_query)
df_temp.index = pd.to_datetime(df_temp["fechaobservacion"])
df_temp.valorobservado = df_temp["valorobservado"].astype(float)
df_temp = df_temp.sort_index()
df_temp.tail()
---------------------------------------------------------------------------
TimeoutError Traceback (most recent call last)
File ~/micromamba/envs/cdh-python/lib/python3.12/site-packages/urllib3/connectionpool.py:534, in HTTPConnectionPool._make_request(self, conn, method, url, body, headers, retries, timeout, chunked, response_conn, preload_content, decode_content, enforce_content_length)
533 try:
--> 534 response = conn.getresponse()
535 except (BaseSSLError, OSError) as e:
File ~/micromamba/envs/cdh-python/lib/python3.12/site-packages/urllib3/connection.py:565, in HTTPConnection.getresponse(self)
564 # Get the response from http.client.HTTPConnection
--> 565 httplib_response = super().getresponse()
567 try:
File ~/micromamba/envs/cdh-python/lib/python3.12/http/client.py:1430, in HTTPConnection.getresponse(self)
1429 try:
-> 1430 response.begin()
1431 except ConnectionError:
File ~/micromamba/envs/cdh-python/lib/python3.12/http/client.py:331, in HTTPResponse.begin(self)
330 while True:
--> 331 version, status, reason = self._read_status()
332 if status != CONTINUE:
File ~/micromamba/envs/cdh-python/lib/python3.12/http/client.py:292, in HTTPResponse._read_status(self)
291 def _read_status(self):
--> 292 line = str(self.fp.readline(_MAXLINE + 1), "iso-8859-1")
293 if len(line) > _MAXLINE:
File ~/micromamba/envs/cdh-python/lib/python3.12/socket.py:720, in SocketIO.readinto(self, b)
719 try:
--> 720 return self._sock.recv_into(b)
721 except timeout:
File ~/micromamba/envs/cdh-python/lib/python3.12/ssl.py:1251, in SSLSocket.recv_into(self, buffer, nbytes, flags)
1248 raise ValueError(
1249 "non-zero flags not allowed in calls to recv_into() on %s" %
1250 self.__class__)
-> 1251 return self.read(nbytes, buffer)
1252 else:
File ~/micromamba/envs/cdh-python/lib/python3.12/ssl.py:1103, in SSLSocket.read(self, len, buffer)
1102 if buffer is not None:
-> 1103 return self._sslobj.read(len, buffer)
1104 else:
TimeoutError: The read operation timed out
The above exception was the direct cause of the following exception:
ReadTimeoutError Traceback (most recent call last)
File ~/micromamba/envs/cdh-python/lib/python3.12/site-packages/requests/adapters.py:667, in HTTPAdapter.send(self, request, stream, timeout, verify, cert, proxies)
666 try:
--> 667 resp = conn.urlopen(
668 method=request.method,
669 url=url,
670 body=request.body,
671 headers=request.headers,
672 redirect=False,
673 assert_same_host=False,
674 preload_content=False,
675 decode_content=False,
676 retries=self.max_retries,
677 timeout=timeout,
678 chunked=chunked,
679 )
681 except (ProtocolError, OSError) as err:
File ~/micromamba/envs/cdh-python/lib/python3.12/site-packages/urllib3/connectionpool.py:841, in HTTPConnectionPool.urlopen(self, method, url, body, headers, retries, redirect, assert_same_host, timeout, pool_timeout, release_conn, chunked, body_pos, preload_content, decode_content, **response_kw)
839 new_e = ProtocolError("Connection aborted.", new_e)
--> 841 retries = retries.increment(
842 method, url, error=new_e, _pool=self, _stacktrace=sys.exc_info()[2]
843 )
844 retries.sleep()
File ~/micromamba/envs/cdh-python/lib/python3.12/site-packages/urllib3/util/retry.py:474, in Retry.increment(self, method, url, response, error, _pool, _stacktrace)
473 if read is False or method is None or not self._is_method_retryable(method):
--> 474 raise reraise(type(error), error, _stacktrace)
475 elif read is not None:
File ~/micromamba/envs/cdh-python/lib/python3.12/site-packages/urllib3/util/util.py:39, in reraise(tp, value, tb)
38 raise value.with_traceback(tb)
---> 39 raise value
40 finally:
File ~/micromamba/envs/cdh-python/lib/python3.12/site-packages/urllib3/connectionpool.py:787, in HTTPConnectionPool.urlopen(self, method, url, body, headers, retries, redirect, assert_same_host, timeout, pool_timeout, release_conn, chunked, body_pos, preload_content, decode_content, **response_kw)
786 # Make the request on the HTTPConnection object
--> 787 response = self._make_request(
788 conn,
789 method,
790 url,
791 timeout=timeout_obj,
792 body=body,
793 headers=headers,
794 chunked=chunked,
795 retries=retries,
796 response_conn=response_conn,
797 preload_content=preload_content,
798 decode_content=decode_content,
799 **response_kw,
800 )
802 # Everything went great!
File ~/micromamba/envs/cdh-python/lib/python3.12/site-packages/urllib3/connectionpool.py:536, in HTTPConnectionPool._make_request(self, conn, method, url, body, headers, retries, timeout, chunked, response_conn, preload_content, decode_content, enforce_content_length)
535 except (BaseSSLError, OSError) as e:
--> 536 self._raise_timeout(err=e, url=url, timeout_value=read_timeout)
537 raise
File ~/micromamba/envs/cdh-python/lib/python3.12/site-packages/urllib3/connectionpool.py:367, in HTTPConnectionPool._raise_timeout(self, err, url, timeout_value)
366 if isinstance(err, SocketTimeout):
--> 367 raise ReadTimeoutError(
368 self, url, f"Read timed out. (read timeout={timeout_value})"
369 ) from err
371 # See the above comment about EAGAIN in Python 3.
ReadTimeoutError: HTTPSConnectionPool(host='www.datos.gov.co', port=443): Read timed out. (read timeout=10)
During handling of the above exception, another exception occurred:
ReadTimeout Traceback (most recent call last)
Cell In[26], line 2
1 # Solicitud de informacion para la estación de la Universidad Nacional - Bogotá - 0021205012
----> 2 temp_query = client.get(
3 dataset_identifier="sbwg-7ju4",
4 select="fechaobservacion, valorobservado, codigoestacion",
5 where="codigoestacion IN ('0021205012') \
6 AND fechaobservacion > '2020'",
7 )
8 df_temp = pd.DataFrame.from_records(temp_query)
9 df_temp.index = pd.to_datetime(df_temp["fechaobservacion"])
File ~/micromamba/envs/cdh-python/lib/python3.12/site-packages/sodapy/socrata.py:412, in Socrata.get(self, dataset_identifier, content_type, **kwargs)
409 params.update(kwargs)
410 params = utils.clear_empty_values(params)
--> 412 response = self._perform_request(
413 "get", resource, headers=headers, params=params
414 )
415 return response
File ~/micromamba/envs/cdh-python/lib/python3.12/site-packages/sodapy/socrata.py:551, in Socrata._perform_request(self, request_type, resource, **kwargs)
548 # set a timeout, just to be safe
549 kwargs["timeout"] = self.timeout
--> 551 response = getattr(self.session, request_type)(uri, **kwargs)
553 # handle errors
554 if response.status_code not in (200, 202):
File ~/micromamba/envs/cdh-python/lib/python3.12/site-packages/requests/sessions.py:602, in Session.get(self, url, **kwargs)
594 r"""Sends a GET request. Returns :class:`Response` object.
595
596 :param url: URL for the new :class:`Request` object.
597 :param \*\*kwargs: Optional arguments that ``request`` takes.
598 :rtype: requests.Response
599 """
601 kwargs.setdefault("allow_redirects", True)
--> 602 return self.request("GET", url, **kwargs)
File ~/micromamba/envs/cdh-python/lib/python3.12/site-packages/requests/sessions.py:589, in Session.request(self, method, url, params, data, headers, cookies, files, auth, timeout, allow_redirects, proxies, hooks, stream, verify, cert, json)
584 send_kwargs = {
585 "timeout": timeout,
586 "allow_redirects": allow_redirects,
587 }
588 send_kwargs.update(settings)
--> 589 resp = self.send(prep, **send_kwargs)
591 return resp
File ~/micromamba/envs/cdh-python/lib/python3.12/site-packages/requests/sessions.py:703, in Session.send(self, request, **kwargs)
700 start = preferred_clock()
702 # Send the request
--> 703 r = adapter.send(request, **kwargs)
705 # Total elapsed time of the request (approximately)
706 elapsed = preferred_clock() - start
File ~/micromamba/envs/cdh-python/lib/python3.12/site-packages/requests/adapters.py:713, in HTTPAdapter.send(self, request, stream, timeout, verify, cert, proxies)
711 raise SSLError(e, request=request)
712 elif isinstance(e, ReadTimeoutError):
--> 713 raise ReadTimeout(e, request=request)
714 elif isinstance(e, _InvalidHeader):
715 raise InvalidHeader(e, request=request)
ReadTimeout: HTTPSConnectionPool(host='www.datos.gov.co', port=443): Read timed out. (read timeout=10)
fig, ax = plt.subplots(figsize=(12, 3))
df_temp["valorobservado"].plot(c="C00", lw=0.5, ax=ax)
4. Datos en tiempo “Causi-real” de IDEAM¶
De igual manera, el IDEAM dispone de una tabla de datos en tiempo cercano a la medición. Esta tabla corresponde al dataset_identifier="57sv-p2fu"
. Generemos una consulta básica para ver los campos contenidos dentro de esta tabla en el último día
time_now = datetime.now()
time = time_now - timedelta(days=10)
time
Convertimos la fecha en un str
para incluirlo en la consulta
time_str = f"{to_datetime(time):%Y-%m-%d}"
time_str
nrt_query = client.get(
dataset_identifier="57sv-p2fu",
select="*",
where="fechaobservacion >= '{}'".format(time_str),
limit=2000,
)
df_nrt = pd.DataFrame.from_records(nrt_query)
df_nrt.head()
Los primeros registros nos indican que hay mediciones cercanas a las fechas de la ejecución de este cuadernillo. Generemos una consulta más específica para la estacion 0024035340
correspondiente al Aeropuerto Alberto Lleras Camargo de Sogamoso.
cod_est = "0024035340"
aero_query = client.get(
dataset_identifier="57sv-p2fu",
select="*",
where="fechaobservacion >= '{}'\
AND codigoestacion IN ('{}')".format(
time_str, cod_est
),
limit=2000,
)
df_aero = pd.DataFrame.from_records(aero_query)
df_aero.head(10)
Para validar los sensores que tiene esta estacion podemo usar el método .unique()
de Pandas
df_aero["codigosensor"].unique()
Podemos centrar aún mas la consulta agregándole el sensor de temperatura codigosensor=0071
cod_sensor = "0071"
aero_query = client.get(
dataset_identifier="57sv-p2fu",
select="fechaobservacion, valorobservado",
where="fechaobservacion >= '{}'\
AND codigoestacion IN ('{}') \
AND codigosensor IN ('{}')".format(
time_str, cod_est, cod_sensor
),
limit=2000,
)
df_aero = pd.DataFrame.from_records(aero_query)
df_aero
Ahora generemos un gráfico rápido de la serie de temperatura para las últimas 24 horas
fig, ax = plt.subplots(figsize=(10, 3))
df_aero.index = pd.to_datetime(df_aero["fechaobservacion"])
df_aero.valorobservado = df_aero["valorobservado"].astype(float)
df_aero.plot(ax=ax)
ax.xaxis.set_major_locator(HourLocator(interval=4)) # tick every four hours
ax.xaxis.set_major_formatter(DateFormatter("%y-%m-%d\n%H:%M"))
Conclusiones¶
En este cuadernillo aprendimos una manera fácil y rápida como acceder a la información histórica y presente de las estaciones hidrometeorológicas del IDEAM. De igual modo aprendimos a visualizar las estaciones usando mapas interactivos. También aprendimos a generar consultas a diferentes grupos de datos usando sintaxis SQL y el aplicativo socrata
de la plataforma de datos abiertos del gobierno Colombiano.
Resources and references¶
- Rose, B. E. J., Kent, J., Tyle, K., Clyne, J., Banihirwe, A., Camron, D., May, R., Grover, M., Ford, R. R., Paul, K., Morley, J., Eroglu, O., Kailyn, L., & Zacharias, A. (2023). Pythia Foundations (Version v2023.05.01) Rose et al. (2023)
- 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