Análisis de la Distribución Geoespacial de las Especies de la Familia Centrolenidae en Costa Rica: Relación con Factores Ambientales¶

Introducción

El presente proyecto tiene como objetivo realizar un análisis geoespacial de la distribución de las especies de la familia Centrolenidae (ranas de cristal) en Costa Rica, mediante el uso de técnicas avanzadas de ciencia de datos y procesamiento de datos geoespaciales. Para ello, se utilizarán conjuntos de datos de observaciones de estas especies, lo que permitirá identificar los patrones espaciales y temporales de su distribución a lo largo del país. Este análisis no solo proporcionará una comprensión más profunda de las áreas de alta biodiversidad, sino que también contribuirá a la identificación de regiones críticas para su conservación, especialmente en el contexto de la creciente pérdida de hábitat y el cambio climático (Fisher, 2023).

Las ranas de cristal, debido a su alta sensibilidad a los cambios ambientales, son consideradas bioindicadores fundamentales para evaluar la salud de los ecosistemas tropicales (Romero, 2023). Sin embargo, a pesar de su importancia ecológica, muchas especies de esta familia están en peligro debido a la deforestación, la contaminación de cuerpos de agua y otros factores antropogénicos (Torres, 2019). La falta de datos actualizados sobre su distribución y estado de conservación es un desafío para el desarrollo de estrategias de protección eficaces.

Este proyecto busca llenar este vacío de información mediante el uso de herramientas de ciencia de datos como Pandas, GeoPandas, y matplotlib en Python, para procesar y visualizar las observaciones de las especies y las variables ambientales asociadas. Además, se emplearán mapas interactivos utilizando Folium, lo que permitirá explorar la distribución geoespacial y su relación con factores ambientales clave como la temperatura, la precipitación y la altitud.

A través de este análisis, se pretende no solo generar conocimiento sobre la distribución actual de las especies de Centrolenidae en Costa Rica, sino también proporcionar una base científica para el diseño de políticas y programas de conservación que ayuden a mitigar los riesgos a los que estas especies están expuestas. Al entender cómo varía la presencia de estas ranas a lo largo del tiempo y el espacio, se podrán implementar estrategias de conservación más efectivas y focalizadas en las áreas más críticas para su preservación.

image.png

Montar Google Drive

In [ ]:
from google.colab import drive
drive.mount('/content/drive')
Mounted at /content/drive

Leer el archivo CSV desde Google Drive

In [ ]:
!pip install gdown
Requirement already satisfied: gdown in /usr/local/lib/python3.11/dist-packages (5.2.0)
Requirement already satisfied: beautifulsoup4 in /usr/local/lib/python3.11/dist-packages (from gdown) (4.13.3)
Requirement already satisfied: filelock in /usr/local/lib/python3.11/dist-packages (from gdown) (3.17.0)
Requirement already satisfied: requests[socks] in /usr/local/lib/python3.11/dist-packages (from gdown) (2.32.3)
Requirement already satisfied: tqdm in /usr/local/lib/python3.11/dist-packages (from gdown) (4.67.1)
Requirement already satisfied: soupsieve>1.2 in /usr/local/lib/python3.11/dist-packages (from beautifulsoup4->gdown) (2.6)
Requirement already satisfied: typing-extensions>=4.0.0 in /usr/local/lib/python3.11/dist-packages (from beautifulsoup4->gdown) (4.12.2)
Requirement already satisfied: charset-normalizer<4,>=2 in /usr/local/lib/python3.11/dist-packages (from requests[socks]->gdown) (3.4.1)
Requirement already satisfied: idna<4,>=2.5 in /usr/local/lib/python3.11/dist-packages (from requests[socks]->gdown) (3.10)
Requirement already satisfied: urllib3<3,>=1.21.1 in /usr/local/lib/python3.11/dist-packages (from requests[socks]->gdown) (2.3.0)
Requirement already satisfied: certifi>=2017.4.17 in /usr/local/lib/python3.11/dist-packages (from requests[socks]->gdown) (2025.1.31)
Requirement already satisfied: PySocks!=1.5.7,>=1.5.6 in /usr/local/lib/python3.11/dist-packages (from requests[socks]->gdown) (1.7.1)
In [ ]:
import gdown

# ID del archivo en Google Drive
file_id = '1pBsKrMhPTpQFQSOYLCroiHwAqwqNaEyW'

# URL para descargar el archivo
url = f'https://drive.google.com/uc?id={file_id}'

# Descargar el archivo CSV
output = 'Centrolenidae.csv'
gdown.download(url, output, quiet=False)
Downloading...
From: https://drive.google.com/uc?id=1pBsKrMhPTpQFQSOYLCroiHwAqwqNaEyW
To: /content/Centrolenidae.csv
100%|██████████| 935k/935k [00:00<00:00, 12.1MB/s]
Out[ ]:
'Centrolenidae.csv'

Leer el archivo CSV en pandas

In [ ]:
import pandas as pd

# Leer el archivo CSV descargado
df = pd.read_csv('Centrolenidae.csv')

# Información general del DataFrame
print(df.info())

# Ver las primeras filas para asegurar que los datos se cargaron correctamente
print(df.head())
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 2566 entries, 0 to 2565
Data columns (total 29 columns):
 #   Column                         Non-Null Count  Dtype  
---  ------                         --------------  -----  
 0   id                             2566 non-null   int64  
 1   observed_on_string             2566 non-null   object 
 2   time_zone                      2566 non-null   object 
 3   user_id                        2566 non-null   int64  
 4   user_login                     2566 non-null   object 
 5   created_at                     2566 non-null   object 
 6   updated_at                     2566 non-null   object 
 7   quality_grade                  2566 non-null   object 
 8   url                            2566 non-null   object 
 9   tag_list                       51 non-null     object 
 10  description                    238 non-null    object 
 11  num_identification_agreements  2566 non-null   int64  
 12  captive_cultivated             2566 non-null   bool   
 13  oauth_application_id           1559 non-null   float64
 14  place_guess                    2556 non-null   object 
 15  latitude                       2566 non-null   float64
 16  longitude                      2566 non-null   float64
 17  positional_accuracy            2169 non-null   float64
 18  private_place_guess            0 non-null      float64
 19  public_positional_accuracy     2209 non-null   float64
 20  geoprivacy                     147 non-null    object 
 21  taxon_geoprivacy               2142 non-null   object 
 22  coordinates_obscured           2566 non-null   bool   
 23  positioning_method             756 non-null    object 
 24  species_guess                  2337 non-null   object 
 25  scientific_name                2566 non-null   object 
 26  common_name                    2516 non-null   object 
 27  iconic_taxon_name              2566 non-null   object 
 28  taxon_id                       2566 non-null   int64  
dtypes: bool(2), float64(6), int64(4), object(17)
memory usage: 546.4+ KB
None
      id observed_on_string                   time_zone  user_id  \
0  18212         2008-05-22  Eastern Time (US & Canada)     1325   
1  18776         2009-12-30             Central America      486   
2  19507         2011-05-28             Central America     1236   
3  22238         2011-05-28             Central America     1236   
4  25203             3/4/11  Pacific Time (US & Canada)     2246   

           user_login               created_at               updated_at  \
0             jplarry  2011-05-25 18:32:07 UTC  2019-09-27 02:32:38 UTC   
1              nito72  2011-05-29 21:29:44 UTC  2020-01-22 16:52:47 UTC   
2  victoracostachaves  2011-05-31 16:30:01 UTC  2024-03-01 13:20:15 UTC   
3  victoracostachaves  2011-06-19 21:04:42 UTC  2021-09-23 21:14:14 UTC   
4             redpine  2011-07-17 05:06:16 UTC  2021-01-23 22:37:31 UTC   

  quality_grade                                            url  \
0      research  http://www.inaturalist.org/observations/18212   
1      research  http://www.inaturalist.org/observations/18776   
2      research  http://www.inaturalist.org/observations/19507   
3      research  http://www.inaturalist.org/observations/22238   
4      research  http://www.inaturalist.org/observations/25203   

                       tag_list  ... public_positional_accuracy  geoprivacy  \
0                           NaN  ...                        NaN         NaN   
1                           NaN  ...                        NaN         NaN   
2    Hyalinobatrachium valerioi  ...                    31218.0    obscured   
3  Hyalinobatrachium talamancae  ...                    10000.0    obscured   
4                           NaN  ...                        NaN         NaN   

   taxon_geoprivacy  coordinates_obscured positioning_method  \
0              open                 False                NaN   
1              open                 False                NaN   
2              open                  True                NaN   
3               NaN                  True                NaN   
4              open                 False                NaN   

              species_guess               scientific_name  \
0  rana de vidrio esmeralda        Espadarana prosoblepon   
1    Reticulated Glass Frog    Hyalinobatrachium valerioi   
2    Reticulated Glass Frog    Hyalinobatrachium valerioi   
3  Green-striped Glass Frog  Hyalinobatrachium talamancae   
4  rana de vidrio esmeralda        Espadarana prosoblepon   

                common_name  iconic_taxon_name  taxon_id  
0  rana de vidrio esmeralda           Amphibia    134933  
1          Ranita de Vidrio           Amphibia     21323  
2          Ranita de Vidrio           Amphibia     21323  
3                       NaN           Amphibia     21357  
4  rana de vidrio esmeralda           Amphibia    134933  

[5 rows x 29 columns]

Revisar y seleccionar columnas relevantes

In [ ]:
print(df.columns.tolist())
['id', 'observed_on_string', 'time_zone', 'user_id', 'user_login', 'created_at', 'updated_at', 'quality_grade', 'url', 'tag_list', 'description', 'num_identification_agreements', 'captive_cultivated', 'oauth_application_id', 'place_guess', 'latitude', 'longitude', 'positional_accuracy', 'private_place_guess', 'public_positional_accuracy', 'geoprivacy', 'taxon_geoprivacy', 'coordinates_obscured', 'positioning_method', 'species_guess', 'scientific_name', 'common_name', 'iconic_taxon_name', 'taxon_id']

Visualización geoespacial

In [ ]:
import folium
import pandas as pd

# Asegurar de que las coordenadas (latitud, longitud) sean válidas y no nulas
df_clean = df.dropna(subset=['latitude', 'longitude'])
df_clean = df_clean[(df_clean['latitude'] >= -90) & (df_clean['latitude'] <= 90)]
df_clean = df_clean[(df_clean['longitude'] >= -180) & (df_clean['longitude'] <= 180)]

# Crear el mapa centrado en Costa Rica
m = folium.Map(location=[9.19, -83.55], zoom_start=7)

# Agregar los puntos de observación al mapa
for index, row in df_clean.iterrows():
    folium.CircleMarker(
        location=[row['latitude'], row['longitude']],
        radius=5,
        color='blue',
        fill=True,
        fill_color='blue',
        fill_opacity=0.6
    ).add_to(m)

# Mostrar el mapa
m
Out[ ]:
Make this Notebook Trusted to load map: File -> Trust Notebook

El mapa de observaciones geográficas muestra cómo se distribuyen las ranas de vidrio en Costa Rica. Al observar los puntos, se pueden identificar áreas con mayor concentración de observaciones, lo que sugiere que algunas regiones son más relevantes para estas especies, posiblemente por características de hábitat específicas como vegetación o cuerpos de agua. Sin embargo, si se encuentran puntos fuera de Costa Rica o dispersos en lugares improbables, esto podría indicar problemas en la precisión de los datos geográficos. Además, la ausencia de puntos en algunas zonas puede señalar vacíos en las observaciones, lo que podría estar relacionado con el acceso limitado o la falta de monitoreo en ciertas áreas.

Este análisis es importante para identificar zonas críticas que podrían necesitar más esfuerzos de conservación y para comprender mejor los patrones de distribución de la especie en el país.

In [ ]:
import pandas as pd

# Datos de ejemplo con coordenadas
data = {
    'latitud': [9.9383, 9.9271, 9.9523],
    'longitud': [-84.0833, -84.0420, -84.0755]
}

# Crear un DataFrame
ranita_df = pd.DataFrame(data)

# Guardar el DataFrame como un archivo CSV
ranita_df.to_csv('/content/ranita_ubicaciones.csv', index=False)

# Ver el archivo creado
print(ranita_df)
   latitud  longitud
0   9.9383  -84.0833
1   9.9271  -84.0420
2   9.9523  -84.0755
In [ ]:
import pandas as pd
import rasterio
from rasterio import sample

# Cargar las coordenadas de la ranita desde el archivo CSV
ranita_df = pd.read_csv('/content/ranita_ubicaciones.csv')

# Abrir el archivo raster de precipitaciones
with rasterio.open('/content/precip_cr.tif') as src:
    # Extraer valores de precipitaciones para las ubicaciones de la ranita
    latitudes = ranita_df['latitud'].values
    longitudes = ranita_df['longitud'].values

    # Crear una lista de las coordenadas (longitud, latitud)
    coords = [(lon, lat) for lon, lat in zip(longitudes, latitudes)]

    # Extraer valores de precipitaciones
    precip_values = [v[0] for v in src.sample(coords)]

# Agregar los valores de precipitaciones al DataFrame de las ubicaciones de la ranita
ranita_df['precipitacion'] = precip_values

# Mostrar los primeros registros
print(ranita_df.head())
   latitud  longitud  precipitacion
0   9.9383  -84.0833            329
1   9.9271  -84.0420            327
2   9.9523  -84.0755            339
In [ ]:
import folium
import pandas as pd
import rasterio
from rasterio import sample

# Cargar las coordenadas de la ranita desde el archivo CSV
ranita_df = pd.read_csv('/content/ranita_ubicaciones.csv')

# Abrir el archivo raster de precipitaciones
with rasterio.open('/content/precip_cr.tif') as src:
    # Extraer valores de precipitaciones para las ubicaciones de la ranita
    latitudes = ranita_df['latitud'].values
    longitudes = ranita_df['longitud'].values

    # Crear una lista de las coordenadas (longitud, latitud)
    coords = [(lon, lat) for lon, lat in zip(longitudes, latitudes)]

    # Extraer valores de precipitaciones
    precip_values = [v[0] for v in src.sample(coords)]

# Agregar los valores de precipitaciones al DataFrame de las ubicaciones de la ranita
ranita_df['precipitacion'] = precip_values

# Crear un mapa centrado en Costa Rica (aproximadamente)
mapa = folium.Map(location=[9.7489, -83.7534], zoom_start=7)

# Agregar las ubicaciones de las ranitas con sus valores de precipitación al mapa
for idx, row in ranita_df.iterrows():
    folium.Marker(
        location=[row['latitud'], row['longitud']],
        popup=f"Precipitación: {row['precipitacion']} mm",
        icon=folium.Icon(color="green", icon="cloud")
    ).add_to(mapa)

# Guardar el mapa en un archivo HTML
mapa.save('/content/mapa_ranitas.html')

# Mostrar el mapa en el notebook
mapa
Out[ ]:
Make this Notebook Trusted to load map: File -> Trust Notebook

Referencias Bibliográficas

Costa Rican Amphibian Research Center. (s.f). Glass Frogs / Ranas de Vidrio. https://cramphibian.com/glass-frogs-ranas-de-vidrio/#:~:text=Ranas%20de%20Vidrio%20de%20Costa,de%20de%20Argentina%20y%20Bolivia.

Fisher, A. (2023). Cómo vive la rana de cristal, la especie única de anfibio que está perdiendo su hábitat en América Latina. National Geographic En Español. https://www.ngenespanol.com/animales/rana-de-cristal/

Forti, L. R., & Szabo, J. K. (2023). The iNaturalist platform as a source of data to study amphibians in Brazil. Anais da Academia Brasileira de Ciências, 95, e20220828.

Heberling, J. M., Miller, J. T., Noesgaard, D., Weingart, S. B., & Schigel, D. (2021). Data integration enables global biodiversity synthesis. Proceedings of the National Academy of Sciences, 118(6), e2018093118.

Rivera, M. (2022).Ranas de cristal. Rev. Acad. Colomb. Cienc. Ex. Fis. Nat. 46(179):585-586, abril-junio de 2022. doi: https://doi.org/10.18257/raccefyn.1714

Romero, R. (2023). ¿Qué tanto sabes de las ranas de cristal? | La trivia de Mongabay Latam. Noticias Ambientales. https://es.mongabay.com/2023/05/que-tanto-sabes-de-ranas-de-cristal-trivia/#:~:text=Las%20ranas%20de%20cristal%20son,un%20impacto%20en%20sus%20poblaciones.

Soberón, J., & Peterson, T. (2004). Biodiversity informatics: managing and applying primary biodiversity data. Philosophical Transactions of the Royal Society of London. Series B: Biological Sciences, 359(1444), 689-698.

Torres, N. (2019). Prpyecto de conservación de anfibios y uso sostenible de los recursos genéticos. Ministerio del Ambiente. https://www.amphibianark.org/wp-content/uploads/2021/11/Reproduccion-de-Atelopus-nanay.pdf

Zhang, J. (2017). Biodiversity science and macroecology in the era of big data. Biodiversity Science, 25(4), 355-363.