Distribución de Lontra longicaudis annectens en México¶

Patricia Steffany Arias Orellana

Resumen:¶

En México Lontra longicaudis annectens, también conocida como nutria de río neotropical, se encuentra distribuida en casi todos los grandes ríos de las planicies costeras, arroyos, lagos, presas y lagunas costeras (Reynoso, 1997).

Esta especie se adapta a una variedad de habitats, desde las regiones áridas con bosque espinoso y matorral, hasta los bosques tropicales perennifolios y subcaducifolios, y desde el nivel del mar con bosque tropical caducifolio, hasta 1,700m en el bosque mesófilo de montaña (Reynoso, 1997).

La población de la nutria de río neotropical está declinando en México por una serie de factores generados por el ser humano: desechos industriales y urbanos, envenenamiento de los ríos, el uso de pequeñas cantidades de TNT para la pesca de subsistencia familiar, la apertura de nuevas áreas para la agricultura y el sistema agrícola de roza, tumba y quema de los bosques tropicales (Reynoso, 1997).

nutria de río

Imagen 1. Nutria de río neotropical

Desarrollo¶

Paquetería inicial¶

In [ ]:
# Cargar geopandas
import geopandas as gpd

# Cargar pandas
import pandas as pd

# Cargar folium
import folium

# Cargar matplotlib
import matplotlib.pyplot as plt

# Carga de plotly.express con el alias px
import plotly.express as px
In [ ]:
# Biblioteca requerida para mapas interactivos
!pip install mapclassify --quiet

import mapclassify
   ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 0.0/59.1 kB ? eta -:--:--
   ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 59.1/59.1 kB 1.7 MB/s eta 0:00:00
In [ ]:
# Instalación de leafmap
!pip install leafmap --quiet

# Instalación de rasterio
!pip install rasterio --quiet

# Instalación de mapclassify
!pip install mapclassify --quiet

# Instalación de localtileserver
!pip install localtileserver --quiet
   ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 0.0/519.2 kB ? eta -:--:--
   ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╺ 512.0/519.2 kB 25.5 MB/s eta 0:00:01
   ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 519.2/519.2 kB 13.2 MB/s eta 0:00:00
   ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 0.0/220.8 kB ? eta -:--:--
   ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 220.8/220.8 kB 14.5 MB/s eta 0:00:00
   ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 0.0/7.7 MB ? eta -:--:--
   ━━━━━━━━━━━━━━━━━━╸━━━━━━━━━━━━━━━━━━━━━ 3.6/7.7 MB 108.5 MB/s eta 0:00:01
   ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╸ 7.7/7.7 MB 112.6 MB/s eta 0:00:01
   ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╸ 7.7/7.7 MB 112.6 MB/s eta 0:00:01
   ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 7.7/7.7 MB 61.2 MB/s eta 0:00:00
   ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 41.4/41.4 kB 2.5 MB/s eta 0:00:00
   ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 108.6/108.6 kB 7.3 MB/s eta 0:00:00
   ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 2.7/2.7 MB 45.1 MB/s eta 0:00:00
   ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 765.5/765.5 kB 30.1 MB/s eta 0:00:00
   ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 194.2/194.2 kB 12.5 MB/s eta 0:00:00
   ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 74.0/74.0 kB 5.6 MB/s eta 0:00:00
   ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 1.6/1.6 MB 48.1 MB/s eta 0:00:00
   ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 22.2/22.2 MB 63.2 MB/s eta 0:00:00
   ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 17.1/17.1 MB 83.6 MB/s eta 0:00:00
   ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 2.8/2.8 MB 74.4 MB/s eta 0:00:00
   ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 267.6/267.6 kB 16.9 MB/s eta 0:00:00
   ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 52.8/52.8 kB 3.7 MB/s eta 0:00:00
   ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 49.5/49.5 kB 3.4 MB/s eta 0:00:00
   ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 195.0/195.0 kB 12.6 MB/s eta 0:00:00
   ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 62.3/62.3 kB 4.1 MB/s eta 0:00:00
In [ ]:
# Para mapas interactivos
import leafmap

# Para datos raster
import rasterio

# Para crear rampas de colores
from matplotlib.colors import LinearSegmentedColormap

# Para álgebra lineal
import numpy as np

# Para permitir widgets de JavaScript
from google.colab import output
output.enable_custom_widget_manager()

Carga de DataFrame¶

In [ ]:
# Cargar archivo CSV con datos de distribución solo de México
nutrias_neo_df = pd.read_csv("https://raw.githubusercontent.com/fanyarellana/nutria-neotropical/refs/heads/main/nutrias-neotropicales-mexico.csv",
                      sep="\t")

# Despliegue de los primeros registros
nutrias_neo_df.head()
Out[ ]:
gbifID datasetKey occurrenceID kingdom phylum class order family genus species ... identifiedBy dateIdentified license rightsHolder recordedBy typeStatus establishmentMeans lastInterpreted mediaType issue
0 686440634 1d04e739-98a9-4e16-9970-8f8f3bf9e9e3 8df64394-1ed8-11e3-bfac-90b11c41863e Animalia Chordata Mammalia Carnivora Mustelidae Lontra Lontra longicaudis ... NaN NaN CC_BY_4_0 NaN CLIFTON P L NaN NaN 2025-03-05T20:57:38.788Z NaN COORDINATE_REPROJECTED
1 686434738 1d04e739-98a9-4e16-9970-8f8f3bf9e9e3 8da1a4db-1ed8-11e3-bfac-90b11c41863e Animalia Chordata Mammalia Carnivora Mustelidae Lontra Lontra longicaudis ... NaN NaN CC_BY_4_0 NaN CLIFTON P L NaN NaN 2025-03-05T20:57:36.434Z NaN COORDINATE_REPROJECTED
2 686429538 1d04e739-98a9-4e16-9970-8f8f3bf9e9e3 8d59c483-1ed8-11e3-bfac-90b11c41863e Animalia Chordata Mammalia Carnivora Mustelidae Lontra Lontra longicaudis ... NaN NaN CC_BY_4_0 NaN CLIFTON P L NaN NaN 2025-03-05T20:57:33.917Z NaN COORDINATE_REPROJECTED
3 686419995 1d04e739-98a9-4e16-9970-8f8f3bf9e9e3 8cf810bf-1ed8-11e3-bfac-90b11c41863e Animalia Chordata Mammalia Carnivora Mustelidae Lontra Lontra longicaudis ... NaN NaN CC_BY_4_0 NaN CLIFTON P L NaN NaN 2025-03-05T20:57:27.601Z NaN COORDINATE_ROUNDED;COORDINATE_REPROJECTED
4 686418941 1d04e739-98a9-4e16-9970-8f8f3bf9e9e3 8ce81805-1ed8-11e3-bfac-90b11c41863e Animalia Chordata Mammalia Carnivora Mustelidae Lontra Lontra longicaudis ... NaN NaN CC_BY_4_0 NaN CLIFTON P L NaN NaN 2025-03-05T20:57:26.601Z NaN COORDINATE_REPROJECTED

5 rows × 50 columns

GeoDataFrame¶

In [ ]:
#Creación de GeoDataFrame a partir del DataFrame
nutrias_neo_gdf = gpd.GeoDataFrame(
    nutrias_neo_df,
    geometry=gpd.points_from_xy(nutrias_neo_df.decimalLongitude, nutrias_neo_df.decimalLatitude),
    crs='EPSG:4326'
)

#Para observar los primeros registros del GeoDataFrame
nutrias_neo_gdf[['gbifID', 'species', 'decimalLongitude', 'decimalLatitude', 'geometry']].head()
Out[ ]:
gbifID species decimalLongitude decimalLatitude geometry
0 686440634 Lontra longicaudis -103.455963 18.962256 POINT (-103.45596 18.96226)
1 686434738 Lontra longicaudis -104.966452 19.385119 POINT (-104.96645 19.38512)
2 686429538 Lontra longicaudis -104.758786 20.458612 POINT (-104.75879 20.45861)
3 686419995 Lontra longicaudis -108.353316 26.934966 POINT (-108.35332 26.93497)
4 686418941 Lontra longicaudis -108.617578 26.416390 POINT (-108.61758 26.41639)

Archivo geoespacial¶

In [ ]:
# Crear un geodataframe con datos y polígonos de paises
paises_gdf = gpd.read_file(
    'https://raw.githubusercontent.com/datos-geoespaciales-biodiversidad/python/refs/heads/main/datos/otros/naturalearth/paises.gpkg',
)

# Mostrar los primeros registros del GeoDataFrame,
paises_gdf[['ADM0_ISO', 'NAME', 'POP_EST', 'GDP_MD', 'geometry']].head()
Out[ ]:
ADM0_ISO NAME POP_EST GDP_MD geometry
0 FJI Fiji 889953.0 5496 MULTIPOLYGON (((180 -16.06713, 180 -16.55522, ...
1 TZA Tanzania 58005463.0 63177 MULTIPOLYGON (((33.90371 -0.95, 34.07262 -1.05...
2 B28 W. Sahara 603253.0 907 MULTIPOLYGON (((-8.66559 27.65643, -8.66512 27...
3 CAN Canada 37589262.0 1736425 MULTIPOLYGON (((-122.84 49, -122.97421 49.0025...
4 USA United States of America 328239523.0 21433226 MULTIPOLYGON (((-122.84 49, -120 49, -117.0312...

Visualización de mapa de distribución¶

In [ ]:
# Crear figura y ejes
fig, ax = plt.subplots(figsize=(8, 6))

# Filtrar de países a México
mexico_gdf = paises_gdf[paises_gdf['ADM0_A3'] == 'MEX'].plot(
    ax=ax,
    color="white",
    edgecolor="black"
)

# Capa de registros de nutrias en América
nutrias_neo_gdf[(nutrias_neo_gdf['decimalLongitude'] < 0) & (nutrias_neo_gdf['decimalLatitude'] < 16)].plot(
    ax=ax,
    marker="o",
    color="brown",
    markersize=50
)
Out[ ]:
<Axes: >
No description has been provided for this image

Gráficos de registro por años¶

In [ ]:
# Borrado de filas que no tengan año
df_anio_no_nulo = nutrias_neo_df.dropna(subset=['year'])

# Filtrado de los años entre 2000 y 2025
df_filtrado = df_anio_no_nulo[(df_anio_no_nulo['year'] >= 2000) & (df_anio_no_nulo['year'] <= 2025)]

# Conteo de registros por año
registros_por_anio = df_filtrado.groupby('year')['gbifID'].count().reset_index()

# Creación del gráfico de barras
fig = px.bar(
    registros_por_anio,
    x='year',
    y='gbifID',
    title='Cantidad de registros (años 2000 - 2025)'
)

# Personalización
fig.update_layout(
    xaxis_title='Año',
    yaxis_title='Cantidad de registros',
    width=1000,    # Ancho de la figura
    height=600     # Alto de la figura
)

Evolución de registros por años¶

In [ ]:
# Borrado de filas que no tengan año
df_anio_no_nulo = nutrias_neo_df.dropna(subset=['year'])

# Conteo de registros por año
registros_por_anio = df_anio_no_nulo.groupby('year')['gbifID'].count().reset_index()
registros_por_anio.columns = ['year', 'count']

# Creación del gráfico de líneas
fig = px.line(
    registros_por_anio,
    x='year',
    y='count',
    markers=True,
    title='Evolución de la cantidad de registros a lo largo de los años'
)

# Personalización
fig.update_layout(
    xaxis_title='Año',
    yaxis_title='Cantidad de registros',
    width=1000,   # Ancho de la figura en píxeles
    height=600    # Alto de la figura en píxeles
)

Los mapas (o el mapa) deben incluir registros de presencia y variables ambientales u otras capas raster relacionadas con la distribución de la especie.

Mapa de distribución en México¶

Carga datos¶

In [ ]:
# Lectura de datos de temperatura media anual
temperatura_media_anual = rasterio.open(
    'https://github.com/gf0657-programacionsig/2024-ii/raw/refs/heads/main/datos/worldclim/altitud.tif'
)
In [ ]:
# Crear un mapa leafmap personalizado
m = leafmap.Map(
    center=(23.6345, -102.5528),
    zoom=5,
    width="500px",
    height="400px"
)

# Agregar el raster al mapa
m.add_raster(
    'https://github.com/datos-geoespaciales-biodiversidad/python/raw/refs/heads/main/datos/clima/worldclim/2.1-10m-bio/wc2.1_10m_bio_1.tif',
    colormap='viridis',
    layer_name='Temperatura media anual'
)

# Desplegar el mapa
m
Map(center=[21.707676, -100.5016], controls=(ZoomControl(options=['position', 'zoom_in_text', 'zoom_in_title',…

Conclusiones¶

  • Se puede observar que hay muy pocos registros de la especie durante los últimos 25 años, con un pico de datos en los años 90.
  • La mayoría de registros de la especie se encuentran distribuidos en la zona Sur de México.

Bibliografía¶

  1. Reynoso, J. P. G. (1997). Situación y Distribuición de las Nutrias en Mexico, con Énfasis en Lontra longicaudis annectens Major, 1897. Revista Mexicana de Mastozoología, 2, 10-32.