Saltar al contenido

# visualizacion-geospacial-avanzada-con-geopandas

Visualización Geospacial Avanzada con GeoPandas

Volver a la portada del curso
Lectura (Markdown)

Manejo de Datos Espaciales

Sección 2 · Análisis de Datos Geoespaciales

Manejo de datos espaciales con GeoPandas

GeoPandas extiende pandas con una idea sencilla: una tabla donde una de las columnas guarda geometrías (puntos, líneas o polígonos). Esa tabla es un GeoDataFrame y se filtra, agrupa y une igual que un DataFrame, pero además sabe calcular áreas, distancias, intersecciones y dibujarse como mapa. Esta lección cubre lo que siempre viene primero: leer datos, entender su sistema de coordenadas, limpiarlos y guardarlos.

El GeoDataFrame y su columna de geometría

Cada fila es una entidad (un estado, una ciudad, un río) y la columna geometry contiene objetos de Shapely. Las operaciones geométricas son vectorizadas: gdf.area o gdf.centroid se calculan para todas las filas a la vez, sin bucles.

Leer datos: archivos, URL y filtros

gpd.read_file lee Shapefile, GeoPackage, GeoJSON y muchos formatos más, desde disco o desde una URL, incluso dentro de un zip. Con where filtras filas con sintaxis SQL antes de cargarlas y con columns eliges qué columnas traer. Aquí cargamos los estados de México desde Natural Earth, un conjunto de datos público:

import geopandas as gpd

URL_ESTADOS = ("https://naciscdn.org/naturalearth/10m/cultural/"
               "ne_10m_admin_1_states_provinces.zip")
estados = gpd.read_file(URL_ESTADOS, where="iso_a2 = 'MX'",
                        columns=["name", "iso_3166_2", "iso_a2"])
print(estados.shape)
print(estados.crs)
print(estados.geom_type.value_counts())

La columna que usas en where debe estar también en columns; si no, la consulta devuelve una tabla vacía sin avisar.

Limpiar antes de analizar

Los datos reales casi nunca llegan perfectos. Esta capa trae 33 registros para 32 entidades: uno no tiene nombre ni tipo. Además, el registro de la capital conserva el nombre «Distrito Federal», que cambió a Ciudad de México en 2016. Revisar y corregir esto al inicio evita errores silenciosos en uniones y gráficas:

print(estados[estados["name"].isna()])
estados = estados.dropna(subset=["name"])
estados["name"] = estados["name"].replace(
    {"Distrito Federal": "Ciudad de México"})
print(len(estados), "entidades")
print(estados.is_valid.all())

is_valid comprueba que los polígonos no se crucen consigo mismos; una geometría inválida puede romper una intersección o una unión. Si aparece alguna, make_valid() suele repararla.

El sistema de coordenadas (CRS)

El CRS dice qué significan los números de cada geometría. EPSG:4326 usa grados de latitud y longitud: sirve para guardar y compartir datos, pero no para medir, porque un grado de longitud mide unos 111 km en el ecuador y mucho menos cerca de los polos. Para calcular áreas y distancias hay que proyectar a un CRS en metros. Para México, EPSG:6372 (Mexico ITRF2008 / LCC, una cónica conforme de Lambert) es una buena opción:

estados_m = estados.to_crs(6372)
estados_m["area_km2"] = estados_m.area / 1e6
print(estados_m.nlargest(3, "area_km2")[["name", "area_km2"]].round(0))
print(f"Total: {estados_m['area_km2'].sum():,.0f} km²")

Chihuahua aparece como el estado más grande, con unos 247,500 km², y el total ronda 1.95 millones de km², cerca de la superficie oficial del país. La diferencia viene de la escala de la capa, que simplifica las costas.

to_crs transforma las coordenadas; set_crs solo etiqueta los datos con un CRS sin cambiarlos. Usa set_crs únicamente cuando el archivo no trae CRS y sabes cuál es el correcto.

De una tabla con coordenadas a puntos

Muchos datos llegan como columnas de longitud y latitud en un CSV. gpd.points_from_xy los convierte en geometrías:

import geopandas as gpd
import pandas as pd

df = pd.DataFrame({"ciudad": ["CDMX", "Guadalajara", "Monterrey"],
                   "lon": [-99.13, -103.35, -100.31],
                   "lat": [19.43, 20.67, 25.69]})
puntos = gpd.GeoDataFrame(df, geometry=gpd.points_from_xy(df.lon, df.lat),
                          crs="EPSG:4326")
puntos_m = puntos.to_crs(6372)
print(puntos_m.distance(puntos_m.geometry.iloc[0]) / 1000)

Las dos últimas líneas calculan la distancia en kilómetros desde la Ciudad de México a cada ciudad, ya en un CRS proyectado.

Guardar el resultado

Prefiere GeoPackage (.gpkg) sobre Shapefile: es un solo archivo, admite nombres de columna largos y acentos, y guarda varias capas. Para datos grandes, GeoParquet (to_parquet) es más rápido y compacto:

# estados.to_file("mexico.gpkg", layer="estados")
# estados.to_parquet("estados.parquet")

Trampas comunes

  • Medir en grados. gdf.area en EPSG:4326 devuelve «grados cuadrados», un número sin sentido. Proyecta primero.
  • Confundir set_crs con to_crs. Etiquetar mal un CRS desplaza todo el mapa sin ningún error.
  • Mezclar capas con CRS distintos. Antes de unir o intersecar, comprueba que a.crs == b.crs.
  • Olvidar la columna del filtro en columns. La lectura devuelve cero filas.

Cierre

Antes de cualquier análisis, revisa cuatro cosas: cuántas filas hay y si alguna sobra, si las geometrías son válidas, cuál es el CRS y si los nombres coinciden con los de las otras tablas que vas a unir.

Recursos