import pandas as pd
from datetime import datetime
from pyinaturalist import get_observations
import ipyplotMis fotos del año 2010
En el año 2010 no estaba activo en iNaturalist, y mantenía la mayoría de mis fotos de fauna y flora en algún respaldo digital, sin mucha estructura o anotaciones. En el proceso de organizar mi colección digital de fotos, he encontrado algunas fotos interesantes de esa época entre respaldos viejos y duplicados.
Para poner estas observaciones de 2010 en contexto temporal de mis contribuciones a iNat, pueden revisar este gráfico
Algunas son observaciones muy interesante, pues en 2010 hice mi primera visita a Sudáfrica (casualmente en el año del Mundial de Fútbol, ¡qué coíncidencia!), y un viaje a México para visitar a mi hermano en Monterrey y Cancún.
En el proceso de subir las fotos a iNaturalist creé este documento que me permite visualizar las fotos que ya están en iNaturalist y así evitar subir fotos por duplicado. La mayoría de las fotos son del viaje a Sudáfrica (Junio), unas pocas del viaje a México (Noviembre), y sólo un par realizadas en Venezuela durante un congreso en la estación biológica de Rancho Grande (Mayo).
Cargar módulos en Python
Importamos los módulos necesarios:
Y declaramos una función útil para leer los datos temporales de la respuesta del API de iNat:
def as_date(x):
if type(x) == str:
y = datetime.strptime(x, "%Y-%m-%d").date()
else:
y = datetime.date(x)
return(y)Descargar observaciones de iNaturalist
Usamos get_observations con un intervalo de fechas que incluye todo el año 2010:
observations = get_observations(user_id='NeoMapas',
d1="2010-01-01",
d2="2010-12-31",
per_page=1000)Este número aumenta a medida que cargamos observaciones en iNat:
len(observations['results'])131
Usamos este loop para guardar la información básica de cada observación:
records=list()
for obs in observations['results']:
record = {
'uri':obs['uri'],
'location': obs['place_guess'],
'species guess': obs['species_guess'],
'Fecha_obs': as_date(obs['observed_on']),
'Fecha_reg': as_date(obs['created_at'])
}
if len(obs['observation_photos'])>0:
record['url'] = obs['observation_photos'][0]['photo']['url'].replace("square","medium")
record['attribution'] = obs['observation_photos'][0]['photo']['attribution']
records.append(record)Y las transformamos en un marco de datos de pandas:
inat_obs=pd.DataFrame(records)Resumen de las observaciones
Agrupamos las observaciones por la localidad y obtenemos una tabla resumen de las observaciones del año:
aggfuns = {
'Fecha_obs': ["min", "max"],
'Fecha_reg': ["min", "max"],
'species guess': ['count',pd.Series.nunique],
}
inat_obs.groupby('location').agg(aggfuns).sort_values(('Fecha_obs','min'))| Fecha_obs | Fecha_reg | species guess | ||||
|---|---|---|---|---|---|---|
| min | max | min | max | count | nunique | |
| location | ||||||
| 88X8+R6W, El Limon 2105, Aragua, Venezuela | 2010-05-06 | 2010-05-06 | 2025-07-24 | 2025-07-24 | 2 | 2 |
| Saint Lucia, South Africa | 2010-06-04 | 2010-06-06 | 2020-07-11 | 2020-07-11 | 10 | 10 |
| Khula Village, South Africa | 2010-06-05 | 2010-06-05 | 2025-07-25 | 2025-07-25 | 1 | 1 |
| uMkhanyakude District Municipality, South Africa | 2010-06-05 | 2010-06-06 | 2025-07-25 | 2025-07-26 | 8 | 8 |
| KwaZulu-Natal, ZA | 2010-06-06 | 2010-06-06 | 2025-07-26 | 2025-07-26 | 1 | 1 |
| St Lucia, 3936, South Africa | 2010-06-06 | 2010-06-06 | 2025-07-26 | 2025-07-26 | 4 | 4 |
| Umkhanyakude, ZA-NL, ZA | 2010-06-07 | 2010-06-07 | 2025-07-24 | 2025-07-24 | 2 | 2 |
| Engwenyeni, South Africa | 2010-06-07 | 2010-06-07 | 2025-07-24 | 2025-07-24 | 14 | 12 |
| Manzibomvu, 3974, South Africa | 2010-06-07 | 2010-06-07 | 2025-07-24 | 2025-07-24 | 3 | 3 |
| Hluhluwe–iMfolozi Park, South Africa | 2010-06-08 | 2010-06-08 | 2025-07-24 | 2025-07-24 | 11 | 9 |
| City of Cape Town, ZA-WC, ZA | 2010-06-09 | 2010-06-09 | 2025-07-26 | 2025-07-26 | 1 | 1 |
| Table Mountain (Nature Reserve), Cape Town, South Africa | 2010-06-09 | 2010-06-09 | 2025-07-26 | 2025-07-26 | 2 | 2 |
| Cape Town City Centre, Cape Town, 8000, South Africa | 2010-06-09 | 2010-06-09 | 2025-07-26 | 2025-07-26 | 3 | 3 |
| Hout Bay Harbour, Cape Town, 7806, South Africa | 2010-06-10 | 2010-06-10 | 2025-03-22 | 2025-03-22 | 3 | 3 |
| Cape Point, Cape Town, South Africa | 2010-06-10 | 2010-06-10 | 2025-03-22 | 2025-07-26 | 4 | 4 |
| Simon's Town, Cape Town, 7975, South Africa | 2010-06-10 | 2010-06-10 | 2025-03-22 | 2025-03-22 | 1 | 1 |
| Vhembe District Municipality, South Africa | 2010-06-14 | 2010-06-15 | 2025-07-25 | 2025-07-26 | 8 | 7 |
| Soutpansberg, South Africa | 2010-06-14 | 2010-06-14 | 2025-07-26 | 2025-07-26 | 1 | 1 |
| Mapungubwe National Park, Musina, South Africa | 2010-06-15 | 2010-06-16 | 2025-07-24 | 2025-07-24 | 22 | 19 |
| Capricorn District Municipality, South Africa | 2010-06-17 | 2010-06-17 | 2025-07-26 | 2025-07-26 | 6 | 6 |
| Mopani District Municipality, South Africa | 2010-06-19 | 2010-06-19 | 2025-07-26 | 2025-07-26 | 6 | 6 |
| Ehlanzeni, ZA-MP, ZA | 2010-06-19 | 2010-06-19 | 2025-07-26 | 2025-07-26 | 1 | 1 |
| Ehlanzeni District Municipality, South Africa | 2010-06-19 | 2010-06-19 | 2025-07-26 | 2025-07-26 | 7 | 6 |
| South Africa | 2010-06-20 | 2010-06-20 | 2025-07-26 | 2025-07-26 | 1 | 1 |
| Monterrey, Nuevo Leon, Mexico | 2010-11-11 | 2010-11-11 | 2024-02-26 | 2024-11-22 | 7 | 7 |
| Cancún, Quintana Roo, Mexico | 2010-11-18 | 2010-11-18 | 2025-07-24 | 2025-07-24 | 2 | 2 |
Filtrar por fecha
Con estas líneas de código podemos filtrar por fecha de observación:
ss = inat_obs['Fecha_obs'].apply(str) == '2010-05-06'
images = inat_obs.loc[ss,'url']
labels = inat_obs.loc[ss,'species guess']
ipyplot.plot_images(list(images), list(labels), max_images=60,)O si preferimos podemos filtrar por fecha en que la observación fue añadida (registrada) en iNat:
ss = inat_obs['Fecha_reg'].apply(str) == '2025-03-22'
images = inat_obs.loc[ss,'url']
labels = inat_obs.loc[ss,'species guess']
ipyplot.plot_images(list(images), list(labels), max_images=60,)Filtrar por localidad
Si queremos filtrar por localidad, simplemente tenemos que cambiar la primera línea:
ss = inat_obs['location'] == 'Saint Lucia, South Africa'
images = inat_obs.loc[ss,'url']
labels = inat_obs.loc[ss,'species guess']
ipyplot.plot_images(list(images), list(labels), max_images=60,)Progreso
Muchos años después todavía estoy en el proceso de registrar todas las fotos de mis viajes del año 2010, pero creo que ya he subido la mayoría de ellas:
aggfuns = {
'Fecha_obs': ["min", "max"],
'location': ['count',pd.Series.nunique],
'species guess': [pd.Series.nunique],
}
inat_obs.groupby('Fecha_reg').agg(aggfuns)| Fecha_obs | location | species guess | |||
|---|---|---|---|---|---|
| min | max | count | nunique | nunique | |
| Fecha_reg | |||||
| 2020-07-11 | 2010-06-04 | 2010-06-06 | 10 | 1 | 10 |
| 2024-02-26 | 2010-11-11 | 2010-11-11 | 1 | 1 | 1 |
| 2024-11-22 | 2010-11-11 | 2010-11-11 | 6 | 1 | 6 |
| 2025-03-22 | 2010-06-10 | 2010-06-10 | 7 | 3 | 7 |
| 2025-07-24 | 2010-05-06 | 2010-11-18 | 56 | 7 | 42 |
| 2025-07-25 | 2010-06-05 | 2010-06-15 | 11 | 3 | 10 |
| 2025-07-26 | 2010-06-06 | 2010-06-20 | 40 | 14 | 36 |
Todas las observaciones
Y cierro aquí con todas las imágenes de las observaciones de este año:
images = inat_obs.sort_values('Fecha_obs')['url']
labels = inat_obs.sort_values('Fecha_obs')['species guess']
ipyplot.plot_images(list(images), list(labels), max_images=200,)