Zum Hauptinhalt springen
tsecurity.de LIVE
Echtzeit-Radar & Feeds
Alle RSS Feeds
👥 Community & Social
YouTube Security VideosfreeCodeCamp.org: TimescaleDB Course – PostgreSQL for Time-Series Data(23.09.2026 um 12:30 Uhr)
Windows Tipps & SecurityAndroid 17: Rollout auf Samsung-Galaxy-Smartphones verzögert sich(23.09.2026 um 11:42 Uhr)
Unix & Linux ServerUSN-8733-2: Gzip vulnerabilities(22.09.2026 um 18:04 Uhr)
Sichere ProgrammierungHow to Build Custom PowerPoint Add-Ins for Enterprise Teams(23.09.2026 um 11:25 Uhr)
Sichere ProgrammierungSearch Google Jobs in Real-Time with Go and SerpApi 🚀(23.09.2026 um 12:13 Uhr)
Sichere ProgrammierungA Psychological State is a Coefficient Vector(23.09.2026 um 12:16 Uhr)
YouTube Security VideosfreeCodeCamp.org: TimescaleDB Course – PostgreSQL for Time-Series Data(23.09.2026 um 12:30 Uhr)
Windows Tipps & SecurityAndroid 17: Rollout auf Samsung-Galaxy-Smartphones verzögert sich(23.09.2026 um 11:42 Uhr)
Unix & Linux ServerUSN-8733-2: Gzip vulnerabilities(22.09.2026 um 18:04 Uhr)
Sichere ProgrammierungHow to Build Custom PowerPoint Add-Ins for Enterprise Teams(23.09.2026 um 11:25 Uhr)
Sichere ProgrammierungSearch Google Jobs in Real-Time with Go and SerpApi 🚀(23.09.2026 um 12:13 Uhr)
Sichere ProgrammierungA Psychological State is a Coefficient Vector(23.09.2026 um 12:16 Uhr)
Intelligence View
⚡ tsecurity.de Intelligence

Cómo comparé registros de coleópteros del Volcán Tacaná usando iNaturalist, GBIF y Python

Cuando se trabaja con datos abiertos de biodiversidad, una de las preguntas más interesantes no es solo cuántos registros pueden descargarse, sino qué cambia cuando se comparan dos infraestructuras distintas sobre el mismo espacio. En este …

0
↗ Quelle (dev.to)
Reagiere als Erste:r — dein Feedback zählt!

Cuando se trabaja con datos abiertos de biodiversidad, una de las preguntas más interesantes no es solo cuántos registros pueden descargarse, sino qué cambia cuando se comparan dos infraestructuras distintas sobre el mismo espacio. En este ejercicio tomé observaciones de coleópteros del entorno del Volcán Tacaná desde iNaturalist y GBIF, las normalicé en un mismo formato y las transformé en salidas cartográficas para comparar visualmente su cobertura, densidad y superposición.



El objetivo no fue hacer scraping por sí mismo, sino construir un flujo reproducible para contrastar resultados y representarlos gráficamente. Para eso usé dos scripts de extracción, una etapa de limpieza tabular y un script final que convirtió los datos en mapas estáticos e interactivos listos para exploración.






Por qué este caso importa



Chiapas es una de las regiones más relevantes de México para el estudio de Coleoptera por su diversidad ambiental, sus gradientes altitudinales y la riqueza documentada en distintos grupos de escarabajos. La literatura regional ha mostrado que el estado concentra una fracción importante de la diversidad nacional en linajes como Scarabaeoidea y Passalidae, y al mismo tiempo conserva vacíos de muestreo que siguen siendo metodológicamente interesantes.



Dentro de ese contexto, el Volcán Tacaná es un buen laboratorio natural. Tiene complejidad topográfica, interés biogeográfico y antecedentes de estudio que lo vuelven ideal para ensayar un flujo de análisis geoespacial con datos reales. Además, comparar iNaturalist con GBIF en una misma ventana espacial permite ver algo que muchas veces se pierde en los inventarios: cada plataforma observa el territorio de forma distinta.






Qué quería resolver



La meta era sencilla de formular, pero útil desde el punto de vista analítico:




  • Descargar registros de coleópteros para el área del Volcán Tacaná.

  • Obtener esos datos desde dos plataformas diferentes.

  • Estandarizar sus campos para que fueran comparables.

  • Limpiarlos lo suficiente para evitar redundancias evidentes.

  • Materializarlos en mapas que permitieran ver coincidencias y diferencias.



En otras palabras, el interés principal era pasar de una pregunta biológica a un flujo de datos geoespaciales reproducible.






Arquitectura del flujo



El pipeline quedó dividido en tres piezas muy concretas. inaturalistscrapper.py recupera observaciones desde iNaturalist, gbifscrapper.py hace lo mismo con GBIF y graficar_mapa.py integra ambos resultados para construir los productos finales.




























Componente Rol técnico Resultado
inaturalistscrapper.py Consulta la API de iNaturalist y normaliza observaciones coleopteros_tacana_inaturalist.csv
gbifscrapper.py Consulta la API de GBIF y normaliza ocurrencias coleopteros_tacana_gbif.csv
graficar_mapa.py Integra ambos CSV, filtra, compara y grafica PNGs y mapa_interactivo_tacana.html


La ventaja de esta estructura es que separa adquisición, transformación y visualización. Si una fuente cambia su API, la modificación afecta solo a su scraper y no al resto del flujo.






Delimitación espacial



Los tres scripts comparten la misma ventana geográfica. El análisis trabaja con un bounding box definido aproximadamente entre 14.9 y 15.2 de latitud y entre -92.3 y -92.0 de longitud, además de registrar la cima del Volcán Tacaná como punto de referencia cartográfica.



Eso es importante porque evita comparar cosas espacialmente distintas. En vez de usar nombres de localidad, límites administrativos o descripciones ambiguas, ambas plataformas se consultan exactamente sobre el mismo recorte espacial.




lat_min, lat_max = 14.9, 15.2
lon_min, lon_max = -92.3, -92.0

tacana_lat = 15.1325
tacana_lon = -92.1086









Extracción desde iNaturalist



Para iNaturalist usé el endpoint de observaciones y filtré por Coleoptera mediante taxon_id = 47208. La búsqueda se restringió con las coordenadas suroeste y noreste del bounding box, y la paginación se resolvió solicitando 200 registros por página.




url = "https://api.inaturalist.org/v1/observations"
params = {
"taxon_id": 47208,
"swlat": 14.9,
"swlng": -92.3,
"nelat": 15.2,
"nelng": -92.0,
"per_page": 200,
"page": 1
}






Cada respuesta JSON contiene bastante información, pero para este flujo extraje solo lo necesario para comparar fuentes: identificador, nombre de la especie, coordenadas, fecha, usuario y calidad del registro. Un detalle importante es que las coordenadas vienen en formato GeoJSON como longitud y latitud, así que hubo que invertir el orden al guardarlas.




all_observations.append({
"id": obs.get("id"),
"especie": obs.get("taxon", {}).get("name"),
"latitud": obs.get("geojson", {}).get("coordinates", [None, None])[1],
"longitud": obs.get("geojson", {}).get("coordinates", [None, None])[0],
"fecha": obs.get("observed_on_string"),
"usuario": obs.get("user", {}).get("login"),
"calidad": obs.get("quality_grade")
})






Ese paso deja a iNaturalist reducido a una tabla simple, lista para integrarse con otra fuente sin arrastrar toda la complejidad de su JSON original.






Extracción desde GBIF



El segundo script trabaja contra el endpoint de ocurrencias de GBIF. Aquí el filtro taxonómico se hace con taxonKey = 1470, y la paginación usa limit y offset, lo que cambia ligeramente la lógica respecto a iNaturalist.




url = "https://api.gbif.org/v1/occurrence/search"
params = {
"taxonKey": 1470,
"decimalLatitude": "14.9,15.2",
"decimalLongitude": "-92.3,-92.0",
"limit": 300,
"offset": 0
}






El script recorre bloques sucesivos de resultados y se detiene cuando GBIF indica que ya no hay más registros o cuando se alcanza el límite operativo de la búsqueda paginada. Después, transforma la respuesta en un esquema tabular análogo al de iNaturalist.




all_observations.append({
"id": obs.get("gbifID"),
"especie": obs.get("species") or obs.get("scientificName"),
"latitud": obs.get("decimalLatitude"),
"longitud": obs.get("decimalLongitude"),
"fecha": obs.get("eventDate"),
"usuario": obs.get("recordedBy"),
"calidad": obs.get("basisOfRecord")
})






Aquí aparece una diferencia metodológica importante: en GBIF, el campo de calidad no equivale al quality_grade de iNaturalist, sino que describe la base del registro. Eso significa que la comparación entre plataformas no es solo espacial, sino también semántica: ambas hablan de biodiversidad, pero no organizan la evidencia de la misma manera.






Limpieza y estandarización



Una vez descargados los datos, ambos scripts convierten las observaciones a un DataFrame de pandas y eliminan duplicados usando una llave compuesta por especie, coordenadas, fecha y usuario. No es una depuración taxonómica completa, pero sí una buena primera barrera contra redundancias obvias.




df = pd.DataFrame(all_observations)
df = df.drop_duplicates(
subset=["especie", "latitud", "longitud", "fecha", "usuario"],
keep="first"
)






Ese detalle hace que la salida de ambos scrapers ya sea comparable desde el punto de vista estructural. El resultado son dos CSV independientes, pero construidos con la misma lógica de campos.






Integración en graficar_mapa.py



El tercer script empieza leyendo ambos CSV y aplicando una segunda capa de control. Si algún archivo no existe, devuelve un DataFrame vacío; si existe, elimina registros sin coordenadas y vuelve a eliminar duplicados.




def cargar_datos(filepath):
if not os.path.exists(filepath):
return pd.DataFrame()
df = pd.read_csv(filepath)
df = df.dropna(subset=["latitud", "longitud"])
df = df.drop_duplicates(
subset=["especie", "latitud", "longitud", "fecha", "usuario"],
keep="first"
)
return df






Me gusta ese patrón porque hace al flujo un poco más tolerante a errores. Aunque la limpieza ya se hizo en los scrapers, el análisis final no depende ciegamente de que todo haya salido perfecto antes.






Mapas estáticos para comparar plataformas



La primera parte de graficar_mapa.py usa Matplotlib para generar salidas PNG. La función principal construye un scatter plot georreferenciado, añade la cima del volcán, dibuja el bounding box y ajusta el rango espacial para que la lectura sea consistente entre mapas.




plt.scatter(df["longitud"], df["latitud"], color=color, alpha=0.6, s=15)
plt.scatter(tacana_lon, tacana_lat, color='red', marker='*', s=200)
plt.plot(rect_x, rect_y, 'g--', alpha=0.5)






A partir de esa función se generan tres productos distintos:




  • Un mapa solo para iNaturalist.

  • Un mapa solo para GBIF.

  • Un mapa comparativo con ambas capas superpuestas.



El comparativo es probablemente la pieza más útil del flujo, porque deja ver de inmediato si las dos plataformas se concentran en las mismas zonas o si cada una ilumina porciones distintas del territorio.



Mapa inaturalist



Mapa Gbif



Mapa Comparativo






Mapa interactivo con Folium



La segunda parte del script materializa un mapa interactivo en HTML usando Folium. El mapa se centra en el Tacaná, arranca con OpenStreetMap y además incorpora una capa satelital de Esri y una capa topográfica.




mapa = folium.Map(location=[tacana_lat, tacana_lon], zoom_start=11, tiles="OpenStreetMap")

folium.TileLayer(
'https://server.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer/tile/{z}/{y}/{x}',
attr='Esri World Imagery',
name='Satélite Esri',
overlay=False
).add_to(mapa)






También se dibuja explícitamente el rectángulo del área de estudio y se añade un marcador para la cima del volcán. Eso ayuda mucho a que la lectura del mapa tenga contexto geográfico y no sea solo una nube de puntos.




folium.Rectangle(
bounds=[[lat_min, lon_min], [lat_max, lon_max]],
color="green",
fill=False,
weight=2,
dash_array="5, 5"
).add_to(mapa)






Mapa Interactivo






Capas separadas y exploración de atributos



Para distinguir visualmente las dos fuentes, el script crea un FeatureGroup para iNaturalist y otro para GBIF. Cada observación se convierte en un CircleMarker con atributos visuales propios de color, tamaño y opacidad.




grupo_inat = folium.FeatureGroup(name=f"iNaturalist ({len(df_inat)} registros)")
for _, r in df_inat.iterrows():
folium.CircleMarker(
location=[r["latitud"], r["longitud"]],
radius=4,
color="#E65100",
fill=True,
fill_color="#FF5722",
fill_opacity=0.8,
tooltip=r["especie"]
).add_to(grupo_inat)






Además, cada punto puede desplegar información contextual como especie, usuario, fecha o tipo de registro. Con LayerControl() el usuario puede activar o desactivar cada plataforma, lo que convierte al entregable en una interfaz ligera de inspección espacial, no solo en una visualización estática.






Qué entregó el pipeline



Al final, el flujo genera una pequeña colección de productos listos para análisis y comunicación:




  • coleopteros_tacana_inaturalist.csv

  • coleopteros_tacana_gbif.csv

  • mapa_observaciones_inaturalist.png

  • mapa_observaciones_gbif.png

  • mapa_comparativa_tacana.png

  • mapa_interactivo_tacana.html



Eso cubre dos necesidades muy comunes en análisis de biodiversidad: producir evidencia visual reproducible para reporte y, al mismo tiempo, conservar una salida interactiva para exploración manual.






Qué deja ver este ejercicio



Lo más interesante de este caso no es la complejidad algorítmica, sino la claridad del flujo. Con decisiones relativamente simples —consultar APIs, estandarizar campos, depurar duplicados y cartografiar resultados— se obtiene una comparación espacial útil entre dos infraestructuras de biodiversidad.



También deja claro algo metodológicamente importante: dos plataformas pueden hablar del mismo grupo biológico y del mismo territorio, pero no necesariamente lo representan igual. Y esa diferencia, lejos de ser un problema, es precisamente lo que hace valioso el ejercicio.






Stack utilizado



El flujo se implementó en Python como lenguaje principal. La comunicación con APIs se resolvió con requests, la manipulación tabular con pandas, la visualización estática con matplotlib y el mapa interactivo con folium.






Software y herramientas computacionales



Ähnliche Beiträge
🔍 Verwandte News

Auch interessante Nachrichten Cómo comparé registros de coleópteros del Volcán Tacaná usando iNaturalist, GBIF y Python

Thematisch verwandte Begriffe: Cómo, comparé, registros, coleópteros · 6 Treffer

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

Zum Aktualisieren ziehen
ZERO-DAY CVE-2026-19438 | Improper Limitation of a Pathname to a Restricted Directory ('Path Trave…
Advisory →
TTS Reader • tsecurity.de Voice
tsecurity.de Icon
tsecurity.de App
Offline-Lesen, Eilmeldungen & 0ms Ladezeit

Installiere tsecurity.de direkt auf deinen Home-Bildschirm für das ultimative Vollbild-Magazinerlebnis ohne Browser-Leisten.

Nächster Beitrag
Themen-Radar & Intelligence Matrix
Echtzeit-Taxonomie nach Angriffsvektoren & Plattformen

tsecurity.de Live Threat Radar

🔴 LIVE RADAR
MONITORING
AKTIV
CVE-DATENBANK
LIVE
🔍
Community Radar & Live Chat
Sentinel Bot online • Live-Stream
Dein Cluster: Security Explorer
Match:
lädt…
Verbindung zum Community-Stream wird aufgebaut...
Bearbeitungsmodus — Senden überschreibt deine Nachricht
Community-Puls — was gerade passiert
lädt…
Aktivitäten deiner Analysten
lädt…
Neues Thema oder Eilmeldung einreichen

Reiche interessante Links, Zero-Days oder Debatten ein. Die Community entscheidet per Upvote über die Veröffentlichung.

Heiß diskutierte Einreichungen
🔖 Gespeicherte Artikel
📂 Keine gespeicherten Artikel vorhanden.
Zurück Ziehen Vor
Links: vorheriger Artikel Rechts: nächster Artikel unten: schließen
News NIS-2 Frühwarnung Tier-1 Intel ⏱️ 3 Min vor 10 Min
Artikeldaten werden geladen...

Zurück: vorheriger Vor: nächster
↗ Original-Quelle
Social Reaktionen Deine Reaktion zählt
Einstufung & Relevanz-Poll 0 Stimmen
In sozialen Netzwerken teilen 1-Klick