Estadísticas de mosquitos y cobertura terrestre#
Esta lección muestra cómo investigar los datos de GLOBE, calcular estadísticas y crear gráficos y mapas.
import pandas as pd
pd.set_option("display.max_columns", None)
import geopandas as gpd
import matplotlib.pyplot as plt
import seaborn as sns
import folium
Mosquitos#
Carguemos los datos directamente desde el enlace. No es necesario descargar ningún archivo en tu computadora.
mosquito = gpd.read_file(
"https://github.com/geo-di-lab/emerge-lessons/raw/"
"refs/heads/main/docs/data/globe_mosquito.zip"
)
mosquito.head()
Consulta la lista de columnas:
mosquito.info()
¿Cuántas filas contiene el conjunto de datos?
len(mosquito)
Entre 2018 y 2024 se registraron 43,012 contribuciones de ciencia participativa. Ahora veamos en cuántos países se enviaron datos.
len(mosquito['CountryCode'].unique())
Veamos los tipos de hábitats, o fuentes de agua, que registraron las personas participantes.
# Categorías generales de fuentes de agua
mosquito["WaterSourceType"].value_counts()
Estas son las categorías generales de fuentes de agua reportadas a NASA mediante GLOBE. La mayoría de los datos parece corresponder a recipientes artificiales. Veamos ahora algunas categorías más específicas de la otra columna:
# Categorías más específicas de fuentes de agua
mosquito["WaterSource"].value_counts()
Creemos un gráfico circular con la columna de categorías generales, WaterSourceType.
# Algunas opciones de paletas de colores
display(sns.color_palette(palette="Set2"))
display(sns.color_palette(palette="twilight_shifted"))
display(sns.color_palette(palette="tab20"))
# Gráfico circular de los tipos de fuentes de agua
types = (
mosquito[["SiteId", "WaterSourceType"]]
.groupby("WaterSourceType", as_index=False)
.count()
)
plt.figure(figsize=(5, 5))
patches, texts = plt.pie(
x=types["SiteId"],
colors=sns.color_palette("Set2")
)
plt.title(
"Observaciones de mosquitos de GLOBE: "
"tipos generales de fuentes de agua"
)
plt.legend(
patches,
types["WaterSourceType"],
loc="center left",
bbox_to_anchor=(1, 0.5),
frameon=False
)
plt.show()
¿Cuál es el promedio de larvas registradas en cada país?
mosquito_avg = (
mosquito.groupby("CountryCode")["LarvaeCountProcessed"]
.mean()
)
mosquito_avg
Creemos un mapa que muestre el promedio de larvas por país. Los límites generalizados de los países proceden de Esri, Garmin y la Agencia Central de Inteligencia de Estados Unidos (The World Factbook). Estos límites se han simplificado para que el procesamiento de datos y las visualizaciones se carguen más rápido.
Los códigos ISO alfa-3 proceden de la capa World Countries, elaborada por Esri, Garmin, la Agencia Central de Inteligencia de Estados Unidos (The World Factbook) y la Organización Internacional de Normalización (ISO).
countries = gpd.read_file(
"https://github.com/geo-di-lab/emerge-lessons/raw/"
"refs/heads/main/docs/data/world_countries_general.geojson"
).to_crs(epsg=4326)
mosquito_avg = countries.merge(
mosquito_avg,
left_on="iso3",
right_on="CountryCode",
how="left"
)
fig, ax = plt.subplots(figsize=(10, 4))
mosquito_avg.plot(
column="LarvaeCountProcessed",
cmap="viridis",
legend=True,
vmin=0,
vmax=50,
ax=ax,
missing_kwds={
"color": "lightgrey",
"label": "Sin datos"
}
)
plt.title(
"Observaciones de mosquitos de GLOBE: "
"promedio de larvas"
)
ax.axis("off")
plt.show()
Ahora crearemos un mapa interactivo que muestre el número total de observaciones de GLOBE por país.
mosquito_obs = (
mosquito.groupby("CountryCode")
.size()
.reset_index(name="GLOBE_Observations")
)
mosquito_obs = countries.merge(
mosquito_obs,
left_on="iso3",
right_on="CountryCode",
how="left"
)
map = folium.Map(
location=[0, 0],
zoom_start=3,
tiles="CartoDB positron"
)
# Crear un mapa con una escala de colores según el número
# de observaciones enviadas a GLOBE
folium.Choropleth(
geo_data=mosquito_obs.to_json(),
name="Observaciones de GLOBE",
data=mosquito_obs,
columns=["name", "GLOBE_Observations"],
key_on="feature.properties.name",
fill_color="YlGnBu",
fill_opacity=0.7,
bins=[1, 50, 100, 500, 1000, 5000, 10000, 20000],
legend_name=(
"Número de observaciones de GLOBE (2018–2024)"
)
).add_to(map)
# Agregar información emergente al pasar el cursor
folium.GeoJson(
geo_data=mosquito_obs.to_json(),
data=mosquito_obs,
key_on="feature.properties.name",
tooltip=folium.features.GeoJsonTooltip(
fields=["name", "GLOBE_Observations"],
aliases=["País:", "Observaciones:"]
),
style_function=lambda feature: {
"color": "white",
"weight": 1
}
).add_to(map)
display(map)
Cobertura terrestre#
Carga los datos de cobertura terrestre directamente desde el enlace.
land_cover = gpd.read_file(
"https://github.com/geo-di-lab/emerge-lessons/raw/"
"refs/heads/main/docs/data/globe_land_cover.zip"
)
land_cover.head()
land_cover.info()
len(land_cover)
Se enviaron ligeramente más observaciones a GLOBE Land Cover, 50,766, que a Mosquito Habitat Mapper.
len(land_cover['CountryCode'].unique())
Una parte útil del conjunto de datos de cobertura terrestre son las clasificaciones MUC. MUC significa Modified UNESCO Classification y es un sistema que reúne distintos tipos de uso y cobertura del suelo.
# Consultar cuántos códigos MUC diferentes aparecen
len(land_cover["MucCode"].unique())
# Identificar el código MUC más común de cada país
muc = (
land_cover.groupby("CountryCode")["MucDescription"]
.apply(
lambda x: (
x.value_counts().idxmax()
if not x.value_counts().empty
else None
)
)
.reset_index(name="MucDescription")
)
# Agregar la cantidad de observaciones del código MUC más común
muc["Count"] = (
land_cover.groupby("CountryCode")["MucDescription"]
.apply(lambda x: x.value_counts().max())
.values
)
# Agregar el número total de observaciones de GLOBE
muc["GLOBE_Observations"] = (
land_cover.groupby("CountryCode")
.size()
.values
)
muc
# Comprobar el cálculo mediante uno de los países
print(
"Cantidad de observaciones del MUC más común:",
len(
land_cover[
(land_cover["CountryCode"] == "USA")
& (
land_cover["MucDescription"]
== "Herbaceous/Grassland, Short Grass"
)
]
)
)
print(
"Total de observaciones de GLOBE:",
len(
land_cover[
land_cover["CountryCode"] == "USA"
]
)
)
La cantidad de filas coincide con la cifra del conjunto de datos anterior, por lo que sabemos que el cálculo se realizó correctamente.
muc = countries.merge(
muc,
left_on="iso3",
right_on="CountryCode",
how="left"
)
Algunas descripciones MUC son similares. Por ello, las agruparemos en categorías generales como Barren, Closed Forest, Cultivated y las demás categorías indicadas a continuación.
Estos valores permanecen en inglés porque deben coincidir exactamente con las descripciones del conjunto de datos.
muc_list = [
"Barren",
"Closed Forest",
"Cultivated",
"Herbaceous",
"Open Water",
"Trees",
"Urban",
"Wetlands",
"Woodland"
]
for muc_code in muc_list:
muc.loc[
muc["MucDescription"].str.contains(
muc_code,
na=False
),
"MucDescriptionShort"
] = muc_code
fig, ax = plt.subplots(figsize=(11, 5))
muc.plot(
column="MucDescriptionShort",
cmap="viridis",
legend=True,
ax=ax,
missing_kwds={
"color": "lightgrey",
"label": "Sin datos"
},
legend_kwds={
"loc": "lower left",
"frameon": False
}
)
plt.title(
"Cobertura terrestre de GLOBE: "
"códigos MUC más comunes"
)
plt.show()
Crearemos un mapa interactivo que muestre el número de observaciones de cobertura terrestre y los códigos MUC más comunes.
map = folium.Map(
location=[0, 0],
zoom_start=3,
tiles="CartoDB positron"
)
# Crear un mapa con una escala de colores según el número
# de observaciones enviadas a GLOBE
folium.Choropleth(
geo_data=muc.to_json(),
name="Observaciones de GLOBE",
data=muc,
columns=["name", "GLOBE_Observations"],
key_on="feature.properties.name",
fill_color="YlGnBu",
fill_opacity=0.7,
bins=[
1, 50, 100, 500, 1000,
5000, 10000, 20000, 30200
],
legend_name=(
"Número de observaciones de GLOBE (2018–2024)"
)
).add_to(map)
# Agregar información emergente al pasar el cursor
folium.GeoJson(
geo_data=muc.to_json(),
data=muc,
key_on="feature.properties.name",
tooltip=folium.features.GeoJsonTooltip(
fields=[
"name",
"MucDescriptionShort",
"GLOBE_Observations"
],
aliases=[
"País:",
"MUC más común:",
"Observaciones:"
]
),
style_function=lambda feature: {
"color": "white",
"weight": 1
}
).add_to(map)
display(map)