import geoquetzal as gq
# Datos censales
df = gq.hogares(departamento="Sacatepequez")
# PCH9_I: ¿Cuenta este hogar con servicio de internet? (1=Sí, 2=No)
acceso_internet = (
df.groupby("MUNICIPIO")["PCH9_I"]
.apply(lambda x: (x == 1).mean() * 100)
.round(1)
.reset_index(name="pct_internet")
)
# Geometría
munis = gq.municipios("Sacatepequez")
# Join por código de municipio
resultado = munis.merge(acceso_internet, left_on="codigo_muni", right_on="MUNICIPIO")
# Mapa interactivo
resultado.explore(
column="pct_internet",
cmap="YlGnBu",
tooltip=["municipio", "pct_internet"],
tooltip_kwds={"aliases": ["Municipio", "% Internet"]},
tiles="CartoDB positron",
style_kwds={"weight": 1, "color": "white", "fillOpacity": 0.8},
)Ejemplos: Censo + Mapas
Esta sección combina datos del Censo 2018 con visualizaciones geográficas. El patrón general es: agregar los microdatos primero, luego hacer merge con la geometría.
Regla clave: Siempre agregue primero (con pandas en Python, con dplyr en R), luego haga merge de la geometría sobre las filas resumen. Nunca use geometry= directamente en microdatos grandes — agrega un polígono a cada fila y es muy lento.
Acceso a Internet por municipio
¿Qué porcentaje de hogares tiene acceso a internet en cada municipio de Sacatepéquez?
library(geoquetzal)
library(dplyr)
library(mapview)
# Datos censales
df <- hogares(departamento = "Sacatepequez")
# PCH9_I: ¿Cuenta este hogar con servicio de internet? (1=Sí, 2=No)
acceso_internet <- df |>
group_by(MUNICIPIO) |>
summarise(pct_internet = round(mean(PCH9_I == 1, na.rm = TRUE) * 100, 1))
# Geometría + join por código de municipio
resultado <- merge(
municipios("Sacatepequez"), acceso_internet,
by.x = "codigo_muni", by.y = "MUNICIPIO"
)
# Mapa interactivo
mapview(resultado,
zcol = "pct_internet",
col.regions = RColorBrewer::brewer.pal(9, "YlGnBu"),
layer.name = "% Internet",
map.types = "CartoDB.Positron",
label = "municipio")Mayoría étnica por municipio
¿Qué grupo étnico es mayoritario en cada municipio de Huehuetenango?
import geoquetzal as gq
df = gq.personas(departamento="Huehuetenango")
# PCP12: autoidentificación étnica (modo = grupo mayoritario)
etnia_dominante = (
df.groupby("MUNICIPIO")["PCP12"]
.agg(lambda x: x.mode()[0])
.reset_index(name="etnia_cod")
)
# Reemplazar códigos por etiquetas
valores = gq.describe_personas("PCP12")["valores"]
etnia_dominante["etnia"] = etnia_dominante["etnia_cod"].map(valores)
# Geometría
munis = gq.municipios("Huehuetenango")
resultado = munis.merge(etnia_dominante, left_on="codigo_muni", right_on="MUNICIPIO")
# Mapa interactivo
resultado.explore(
column="etnia",
tooltip=["municipio", "etnia"],
tooltip_kwds={"aliases": ["Municipio", "Grupo Étnico Mayoritario"]},
tiles="CartoDB positron",
style_kwds={"weight": 1, "color": "white"},
)library(geoquetzal)
library(dplyr)
library(mapview)
df <- personas(departamento = "Huehuetenango")
# PCP12: autoidentificación étnica (modo = grupo mayoritario)
etnia_dominante <- df |>
group_by(MUNICIPIO) |>
summarise(etnia_cod = as.integer(names(which.max(table(PCP12))))) |>
mutate(etnia = recode(as.character(etnia_cod),
"1" = "Maya", "2" = "Garífuna", "3" = "Xinka",
"4" = "Afrodescendiente", "5" = "Ladino", "6" = "Extranjero"))
# Geometría + join
resultado <- merge(
municipios("Huehuetenango"), etnia_dominante,
by.x = "codigo_muni", by.y = "MUNICIPIO"
)
# Mapa interactivo
mapview(resultado,
zcol = "etnia",
map.types = "CartoDB.Positron",
label = "municipio",
layer.name = "Grupo Étnico Mayoritario")Emigración por departamento
¿Cuántas personas emigraron desde cada departamento entre 2002 y 2018?
import geoquetzal as gq
df = gq.emigracion()
# Total de emigrantes por departamento
emigracion = (
df.groupby("DEPARTAMENTO")
.size()
.reset_index(name="emigrantes")
)
deptos = gq.departamentos()
resultado = deptos.merge(emigracion, left_on="codigo_depto", right_on="DEPARTAMENTO")
resultado.explore(
column="emigrantes",
cmap="OrRd",
tooltip=["departamento", "emigrantes"],
tooltip_kwds={"aliases": ["Departamento", "Emigrantes"]},
tiles="CartoDB positron",
style_kwds={"weight": 1, "color": "white", "fillOpacity": 0.8},
)library(geoquetzal)
library(dplyr)
library(mapview)
df <- emigracion()
# Total de emigrantes por departamento
emigracion_agg <- df |>
group_by(DEPARTAMENTO) |>
summarise(emigrantes = n())
resultado <- merge(
departamentos(), emigracion_agg,
by.x = "codigo_depto", by.y = "DEPARTAMENTO"
)
mapview(resultado,
zcol = "emigrantes",
col.regions = RColorBrewer::brewer.pal(9, "OrRd"),
layer.name = "Emigrantes",
map.types = "CartoDB.Positron",
label = "departamento")Coropleta sub-municipal con Voronoi
Acceso a internet a nivel de lugar poblado en Antigua Guatemala — primera visualización sub-municipal disponible para Guatemala.
import geoquetzal as gq
# Polígonos Voronoi (aproximación de límites sub-municipales)
vor = gq.voronoi_lugares_poblados(municipio="Antigua Guatemala") ℹ 2 lugares poblados excluidos por coordenadas nulas (códigos terminados en 999 — asentamientos sin nombre oficial).
✓ 57 polígonos Voronoi generados
# Datos censales pre-agregados por lugar poblado
lp = gq.lugares_poblados(municipio="Antigua Guatemala")
lp = lp.drop(columns=["nombre", "lat", "longitud", "area"])
# Join
gdf = vor.merge(lp, on=["departamento", "municipio", "lugar_poblado"])
# Calcular % de hogares con internet
gdf["pct_internet"] = (
gdf["pch9_i_si"] / (gdf["pch9_i_si"] + gdf["pch9_i_no"]) * 100
).round(1)
# Mapa interactivo con hover
gdf.explore(
column="pct_internet",
cmap="YlGnBu",
tooltip=["nombre", "pct_internet"],
tooltip_kwds={"aliases": ["Lugar Poblado", "% con Internet"]},
popup=["nombre", "pct_internet", "pch9_i_si", "pch9_i_no"],
popup_kwds={"aliases": [
"Lugar Poblado", "% con Internet",
"Hogares con Internet", "Hogares sin Internet"
]},
legend=True,
tiles="CartoDB positron",
style_kwds={"weight": 0.5, "color": "white"},
)library(geoquetzal)
library(mapview)
# Polígonos Voronoi (aproximación de límites sub-municipales)
vor <- voronoi_lugares_poblados(municipio = "Antigua Guatemala")
# Datos censales pre-agregados por lugar poblado
lp <- lugares_poblados(municipio = "Antigua Guatemala")
lp <- lp[, !names(lp) %in% c("nombre", "lat", "longitud", "area")]
# Join
gdf <- merge(vor, lp, by = c("departamento", "municipio", "lugar_poblado"))
# Calcular % de hogares con internet
gdf$pct_internet <- round(
gdf$pch9_i_si / (gdf$pch9_i_si + gdf$pch9_i_no) * 100, 1
)
# Mapa interactivo
mapview(gdf,
zcol = "pct_internet",
col.regions = RColorBrewer::brewer.pal(9, "YlGnBu"),
layer.name = "% Internet",
map.types = "CartoDB.Positron",
lwd = 0.5,
color = "white",
label = "nombre")Los polígonos Voronoi son aproximaciones para visualización — el INE no publica límites oficiales de lugares poblados. Cada polígono representa la zona de influencia del centroide del lugar poblado dentro de su municipio.
Porcentaje de población Maya por lugar poblado
import geoquetzal as gq
vor = gq.voronoi_lugares_poblados(departamento="Sacatepequez") ℹ 22 lugares poblados excluidos por coordenadas nulas (códigos terminados en 999 — asentamientos sin nombre oficial).
✓ 237 polígonos Voronoi generados
lp = gq.lugares_poblados(departamento="Sacatepequez")
lp = lp.drop(columns=["nombre", "lat", "longitud", "area"])
gdf = vor.merge(lp, on=["departamento", "municipio", "lugar_poblado"])
# Usar total de respondidos como denominador (excluir nulos)
pcp12_cols = [c for c in gdf.columns if c.startswith("pcp12_") and c != "pcp12_nulo"]
gdf["pcp12_total_respondido"] = gdf[pcp12_cols].sum(axis=1)
gdf["pct_maya"] = (
gdf["pcp12_maya"] / gdf["pcp12_total_respondido"] * 100
).round(1)
gdf.explore(
column="pct_maya",
cmap="Purples",
tooltip=["nombre", "pct_maya"],
tooltip_kwds={"aliases": ["Lugar Poblado", "% Población Maya"]},
legend=True,
tiles="CartoDB positron",
style_kwds={"weight": 0.5, "color": "white"},
)library(geoquetzal)
library(mapview)
vor <- voronoi_lugares_poblados(departamento = "Sacatepequez")
lp <- lugares_poblados(departamento = "Sacatepequez")
lp <- lp[, !names(lp) %in% c("nombre", "lat", "longitud", "area")]
gdf <- merge(vor, lp, by = c("departamento", "municipio", "lugar_poblado"))
# Usar total de respondidos como denominador (excluir nulos)
pcp12_cols <- grep("^pcp12_", names(gdf), value = TRUE)
pcp12_cols <- pcp12_cols[pcp12_cols != "pcp12_nulo"]
gdf$pcp12_total_respondido <- rowSums(as.data.frame(gdf)[, pcp12_cols], na.rm = TRUE)
gdf$pct_maya <- round(gdf$pcp12_maya / gdf$pcp12_total_respondido * 100, 1)
mapview(gdf,
zcol = "pct_maya",
col.regions = RColorBrewer::brewer.pal(9, "Purples"),
layer.name = "% Población Maya",
map.types = "CartoDB.Positron",
lwd = 0.5,
color = "white",
label = "nombre")Piso de tierra como indicador socioeconómico
import geoquetzal as gq
vor = gq.voronoi_lugares_poblados(departamento="Sacatepequez") ℹ 22 lugares poblados excluidos por coordenadas nulas (códigos terminados en 999 — asentamientos sin nombre oficial).
✓ 237 polígonos Voronoi generados
lp = gq.lugares_poblados(departamento="Sacatepequez")
lp = lp.drop(columns=["nombre", "lat", "longitud", "area"])
gdf = vor.merge(lp, on=["departamento", "municipio", "lugar_poblado"])
# pcv5_tierra = viviendas con piso de tierra
gdf["pct_tierra"] = (
gdf["pcv5_tierra"] / gdf["poblacion_total"] * 100
).round(1)
gdf.explore(
column="pct_tierra",
cmap="YlOrBr",
tooltip=["nombre", "pct_tierra"],
tooltip_kwds={"aliases": ["Lugar Poblado", "% Piso de Tierra"]},
legend=True,
tiles="CartoDB positron",
style_kwds={"weight": 0.5, "color": "white"},
)library(geoquetzal)
library(mapview)
vor <- voronoi_lugares_poblados(departamento = "Sacatepequez")
lp <- lugares_poblados(departamento = "Sacatepequez")
lp <- lp[, !names(lp) %in% c("nombre", "lat", "longitud", "area")]
gdf <- merge(vor, lp, by = c("departamento", "municipio", "lugar_poblado"))
# pcv5_tierra = viviendas con piso de tierra
gdf$pct_tierra <- round(gdf$pcv5_tierra / gdf$poblacion_total * 100, 1)
mapview(gdf,
zcol = "pct_tierra",
col.regions = RColorBrewer::brewer.pal(9, "YlOrBr"),
layer.name = "% Piso de Tierra",
map.types = "CartoDB.Positron",
lwd = 0.5,
color = "white",
label = "nombre")