Analiza Datos Geográficos con GeoPandas: Crea Mapas Temáticos en Python
Este tutorial te guiará paso a paso en el uso de GeoPandas, una potente librería de Python para trabajar con datos geoespaciales. Aprenderás a cargar, manipular y visualizar datos geográficos, creando mapas temáticos informativos y visualmente atractivos. Ideal para científicos de datos, analistas y entusiastas de la geografía.
🗺️ Introducción a GeoPandas: Tu Puerta al Análisis Geoespacial
El análisis de datos geográficos se ha convertido en una disciplina fundamental en una multitud de campos, desde la planificación urbana y la gestión ambiental hasta la logística y el marketing. Poder visualizar y entender cómo los datos se distribuyen en el espacio nos brinda insights únicos que los análisis tradicionales a menudo pasan por alto.
Aquí es donde entra GeoPandas, una extensión de la popular librería Pandas que facilita enormemente el trabajo con datos geoespaciales en Python. GeoPandas combina la familiaridad y eficiencia de Pandas para la manipulación de datos tabulares con las capacidades geoespaciales de librerías como Shapely para objetos geométricos y Fiona para el acceso a archivos de datos espaciales. En esencia, te permite realizar operaciones de Sistemas de Información Geográfica (SIG) directamente en tu entorno Python.
Este tutorial te equipará con los conocimientos y herramientas necesarias para empezar a explorar y visualizar tus propios datos geográficos, creando mapas temáticos que cuenten una historia.
¿Por qué GeoPandas? 🤔
Si ya estás familiarizado con Pandas, te sentirás como en casa con GeoPandas. Extiende los DataFrame y Series de Pandas para incluir una columna especial llamada geometry, que almacena objetos geométricos como puntos, líneas o polígonos. Esto permite realizar operaciones espaciales de forma intuitiva, combinándolas con las poderosas capacidades de filtrado y manipulación de datos de Pandas.
🛠️ Configuración del Entorno: Preparando el Terreno
Antes de empezar a escribir código, necesitamos asegurarnos de que tenemos todas las librerías necesarias instaladas. La forma más recomendada de instalar GeoPandas y sus dependencias es utilizando conda o pip.
Instalación con Conda (Recomendado) 🐍
Si utilizas Anaconda o Miniconda, la instalación es sencilla y resuelve automáticamente las dependencias, incluyendo fiona, shapely, pyproj y rtree.
conda install geopandas
Instalación con Pip (Alternativa) 📦
Si prefieres pip, ten en cuenta que puede requerir la instalación manual de algunas dependencias binarias o que tengas las herramientas de compilación adecuadas en tu sistema.
pip install geopandas
Verifica tu instalación abriendo un intérprete de Python e importando la librería:
import geopandas as gpd
print(gpd.__version__)
Si no obtienes errores y ves la versión de GeoPandas, ¡estás listo!
📖 Conceptos Clave en GeoPandas
Antes de sumergirnos en el código, es crucial entender algunos conceptos fundamentales:
GeoDataFrame y GeoSeries
Al igual que Pandas tiene DataFrame y Series, GeoPandas introduce GeoDataFrame y GeoSeries. Un GeoDataFrame es un DataFrame de Pandas que tiene una columna geometry especial. Esta columna contiene objetos Shapely que representan características geográficas (puntos, líneas, polígonos). Un GeoSeries es una Series que contiene solo objetos geométricos.
Geometrías (Shapely) 📍📏🏞️
GeoPandas utiliza la librería Shapely para manejar los objetos geométricos. Los tipos de geometrías más comunes son:
- Point: Un único par de coordenadas (x, y).
- LineString: Una secuencia de puntos conectados que forman una línea.
- Polygon: Una secuencia de puntos conectados que forman un área cerrada, con un exterior y opcionalmente interiores (agujeros).
- MultiPoint, MultiLineString, MultiPolygon: Colecciones de los tipos anteriores.
Sistemas de Coordenadas de Referencia (CRS) 🌐
El CRS (Coordinate Reference System) es vital para cualquier dato geoespacial. Define cómo las coordenadas de tus geometrías se mapean a ubicaciones en la Tierra. Es como el 'idioma' en el que están tus coordenadas. Los CRS se pueden especificar usando códigos EPSG (European Petroleum Survey Group) o strings PROJ. Por ejemplo, EPSG:4326 es el sistema de coordenadas geográficas WGS84, comúnmente usado para latitud/longitud. EPSG:3857 es el CRS de Web Mercator, popular en mapas web.
🚀 Primeros Pasos: Cargando y Explorando Datos Geográficos
Para este tutorial, utilizaremos datos geográficos comunes disponibles públicamente. Un buen punto de partida son los datos de los países del mundo. Puedes descargar un shapefile (.shp) o un archivo GeoJSON de fuentes como Natural Earth Data.
💾 Descargando Datos de Ejemplo
Para facilitar el ejemplo, usaremos el conjunto de datos de países de GeoPandas mismo, que se descarga automáticamente la primera vez que se accede.
import geopandas as gpd
import matplotlib.pyplot as plt
# Cargar el conjunto de datos de países de ejemplo de GeoPandas
world = gpd.read_file(gpd.datasets.get_path('naturalearth_lowres'))
# Mostrar las primeras filas del GeoDataFrame
print(world.head())
# Mostrar información general del GeoDataFrame
print(world.info())
# Obtener el CRS del GeoDataFrame
print(f"CRS actual: {world.crs}")
# Plotear el mundo básico
world.plot(figsize=(10, 6))
plt.title('Mapa Básico del Mundo')
plt.xlabel('Longitud')
plt.ylabel('Latitud')
plt.show()
Este código carga los datos de países, muestra las primeras filas para que veas su estructura, su CRS y luego los plotea. Notarás que la columna geometry es el corazón de tu GeoDataFrame.
| Columna | Descripción |
|---|---|
| --- | --- |
pop_est | Población estimada |
continent | Continente al que pertenece el país |
| --- | --- |
name | Nombre del país |
iso_a3 | Código ISO A3 del país |
| --- | --- |
gdp_md_est | PIB estimado en millones de USD |
geometry | Objeto geométrico (generalmente un MultiPolygon) |
🔍 Inspeccionando las Geometrías
Puedes acceder a las geometrías de un país específico. Por ejemplo, veamos la geometría de España:
espana = world[world['name'] == 'Spain']
print(type(espana.geometry.iloc[0]))
print(espana.geometry.iloc[0])
Esto te mostrará que la geometría de España es un MultiPolygon y te imprimirá sus coordenadas. Los objetos Shapely tienen métodos y atributos útiles para interactuar con ellos, como area, length, bounds, etc.
📊 Manipulación de Datos Geográficos
GeoPandas sobresale en la manipulación de datos espaciales. Aquí exploraremos algunas operaciones comunes.
🌍 Filtrado y Selección Espacial
Al igual que en Pandas, puedes filtrar filas basándote en valores de columna. Para el filtrado espacial, usamos métodos de GeoPandas.
Por ejemplo, seleccionemos solo los países de Europa:
euro_countries = world[world['continent'] == 'Europe']
euro_countries.plot(figsize=(10, 6), color='lightgreen', edgecolor='black')
plt.title('Países de Europa')
plt.show()
🔄 Reproyectar CRS
Es común trabajar con diferentes CRS. Para asegurar la compatibilidad y realizar mediciones precisas (áreas, distancias) en unidades métricas, a menudo necesitamos reproyectar nuestros datos a un CRS proyectado. El CRS original de naturalearth_lowres es EPSG:4326 (WGS84, lat/lon), que usa grados.
Para calcular áreas en kilómetros cuadrados, por ejemplo, necesitamos un CRS proyectado. Usaremos un CRS universal como EPSG:3857 (Web Mercator) para nuestro ejemplo.
# Reproyectar a Web Mercator (EPSG:3857)
world_projected = world.to_crs(epsg=3857)
# Comparar los CRS
print(f"CRS original: {world.crs}")
print(f"CRS proyectado: {world_projected.crs}")
# Calcular el área en kilómetros cuadrados (aproximado en Web Mercator)
world_projected['area_sqkm'] = world_projected.geometry.area / 10**6 # Convertir m^2 a km^2
print(world_projected[['name', 'area_sqkm']].sort_values(by='area_sqkm', ascending=False).head())
🧩 Uniones Espaciales (sjoin)
Una de las características más potentes de GeoPandas es la capacidad de realizar uniones espaciales. Esto es similar a un merge de Pandas, pero en lugar de unir por un valor de columna, lo hace basándose en la relación espacial entre las geometrías.
Los tipos de uniones espaciales incluyen:
intersects: Si las geometrías se cruzan.within: Si una geometría está completamente dentro de otra.contains: Si una geometría contiene completamente a otra.
Imaginemos que tenemos un GeoDataFrame de ciudades y otro de países, y queremos saber a qué país pertenece cada ciudad. Esto sería una unión espacial within.
Para este ejemplo, crearemos un GeoDataFrame simple de puntos aleatorios para simular ciudades en Europa y los uniremos espacialmente con los países europeos.
from shapely.geometry import Point
import numpy as np
# Crear puntos aleatorios (simulando ciudades) dentro de un rango para Europa
np.random.seed(42)
cities_data = {
'name': [f'Ciudad_{i}' for i in range(10)],
'latitude': np.random.uniform(35, 70, 10),
'longitude': np.random.uniform(-10, 30, 10)
}
cities_gdf = gpd.GeoDataFrame(
cities_data,
geometry=gpd.points_from_xy(cities_data['longitude'], cities_data['latitude']),
crs="EPSG:4326" # Asegúrate de que el CRS sea el mismo que el de los países
)
# Cargar países europeos (asegurándonos de que esté en EPSG:4326)
euro_countries_4326 = world[world['continent'] == 'Europe'].to_crs(epsg=4326)
# Realizar la unión espacial (sjoin)
cities_with_country = gpd.sjoin(cities_gdf, euro_countries_4326, how="inner", predicate="within")
print(cities_with_country[['name_left', 'name_right', 'geometry']].head())
# name_left es el nombre de la ciudad, name_right es el nombre del país
# Visualizar la unión espacial
fig, ax = plt.subplots(1, 1, figsize=(12, 8))
euro_countries_4326.plot(ax=ax, color='lightgray', edgecolor='black')
cities_with_country.plot(ax=ax, marker='o', color='red', markersize=50, label='Ciudades en Países')
plt.title('Ciudades unidas espacialmente a países europeos')
plt.legend()
plt.show()
📈 Agregación Geoespacial
Puedes realizar agregaciones espaciales para resumir datos. Por ejemplo, podríamos calcular la población total por continente.
# Agrupar por continente y sumar la población estimada
pop_by_continent = world.groupby('continent')['pop_est'].sum().sort_values(ascending=False)
print(pop_by_continent)
# Unir estos datos de población de nuevo al GeoDataFrame de continentes (si tuviéramos uno)
# O simplemente usarlo para colorear un mapa temático.
🎨 Creando Mapas Temáticos Atractivos
La visualización es clave en el análisis geoespacial. GeoPandas se integra perfectamente con Matplotlib para crear mapas temáticos.
Mapa Coroplético Básico 📊
Un mapa coroplético colorea las regiones basándose en el valor de una variable. Crearemos un mapa que muestre la población estimada de los países.
fig, ax = plt.subplots(1, 1, figsize=(15, 10))
world.plot(
column='pop_est', # Columna para colorear
cmap='viridis', # Mapa de colores
linewidth=0.8, # Grosor de la línea del borde
ax=ax, # Objeto Axes de Matplotlib
edgecolor='0.8', # Color del borde
legend=True, # Mostrar leyenda de colores
legend_kwds={'label': "Población Estimada", 'orientation': "horizontal"}
)
ax.set_title('Población Estimada por País (2020)', fontsize=15)
ax.set_axis_off() # Ocultar ejes
plt.show()
📍 Añadiendo Puntos a un Mapa
Podemos superponer diferentes tipos de geometrías. Por ejemplo, si tenemos un GeoDataFrame de capitales mundiales, podemos añadirlas a nuestro mapa de países.
# Datos de capitales (ejemplo simplificado)
capital_data = {
'name': ['Madrid', 'Paris', 'Berlin', 'London'],
'latitude': [40.4168, 48.8566, 52.5200, 51.5074],
'longitude': [-3.7038, 2.3522, 13.4050, -0.1278]
}
capital_gdf = gpd.GeoDataFrame(
capital_data,
geometry=gpd.points_from_xy(capital_data['longitude'], capital_data['latitude']),
crs="EPSG:4326"
)
fig, ax = plt.subplots(1, 1, figsize=(15, 10))
# Plotear los países (solo Europa para mayor claridad)
euro_countries_4326.plot(ax=ax, color='lightgray', edgecolor='black')
# Plotear las capitales
capital_gdf.plot(ax=ax, marker='*', color='red', markersize=200, label='Capitales', edgecolor='black')
# Añadir etiquetas a las capitales
for x, y, label in zip(capital_gdf.geometry.x, capital_gdf.geometry.y, capital_gdf['name']):
ax.annotate(label, xy=(x, y), xytext=(3, 3), textcoords="offset points", fontsize=9)
ax.set_title('Capitales Europeas', fontsize=15)
ax.set_axis_off()
plt.legend()
plt.show()
Combinando múltiples capas y estilos avanzados
Para mapas más complejos, puedes combinar varias capas (GeoDataFrames) en el mismo Axes de Matplotlib, aplicando diferentes estilos y transparencias.
# Ejemplo: Mapa de Europa con países por PIB y capitales
fig, ax = plt.subplots(1, 1, figsize=(15, 10))
# 1. Capa de países europeos coloreados por PIB (normalizado para mejor visualización)
euro_countries_4326['gdp_normalized'] = np.log1p(euro_countries_4326['gdp_md_est']) # Usar log para suavizar grandes diferencias
euro_countries_4326.plot(
column='gdp_normalized',
cmap='YlGnBu', # Otro mapa de colores
linewidth=0.8,
ax=ax,
edgecolor='0.8',
legend=True,
legend_kwds={'label': "PIB Estimado (logarítmico)", 'orientation': "horizontal"}
)
# 2. Capa de capitales
capital_gdf.plot(ax=ax, marker='o', color='purple', markersize=100, label='Capitales', edgecolor='white', alpha=0.7)
# Añadir etiquetas de las capitales
for x, y, label in zip(capital_gdf.geometry.x, capital_gdf.geometry.y, capital_gdf['name']):
ax.annotate(label, xy=(x, y), xytext=(5, 5), textcoords="offset points", fontsize=8, color='black')
ax.set_title('PIB Estimado y Capitales en Europa', fontsize=16)
ax.set_axis_off()
plt.legend()
plt.show()
✨ Operaciones Geométricas Avanzadas
GeoPandas, al basarse en Shapely, permite realizar una amplia gama de operaciones geométricas.
📏 Búfer (buffer)
Crear un búfer alrededor de una geometría genera una nueva geometría que representa un área a una distancia específica de la original. Esto es útil para zonas de influencia.
# Crear un búfer de 2 grados alrededor de Madrid (CRS 4326 usa grados)
madrid_point = capital_gdf[capital_gdf['name'] == 'Madrid'].geometry.iloc[0]
madrid_buffer = madrid_point.buffer(2) # 2 grados de latitud/longitud
# Para un búfer en unidades métricas, primero reproyecta a un CRS proyectado
madrid_point_proj = capital_gdf[capital_gdf['name'] == 'Madrid'].to_crs(epsg=3857).geometry.iloc[0]
madrid_buffer_km = madrid_point_proj.buffer(200_000) # 200 km en metros
# Visualizar el búfer (reproyectar el buffer de vuelta a 4326 para plotear con el mapa mundial)
madrid_buffer_km_4326 = gpd.GeoSeries([madrid_buffer_km], crs='EPSG:3857').to_crs(epsg=4326)
fig, ax = plt.subplots(1, 1, figsize=(10, 8))
world[world['name'].isin(['Spain', 'France', 'Portugal'])].plot(ax=ax, color='lightgray', edgecolor='black')
gpd.GeoSeries([madrid_point], crs='EPSG:4326').plot(ax=ax, color='red', marker='*', markersize=200, label='Madrid')
madrid_buffer_km_4326.plot(ax=ax, color='blue', alpha=0.3, label='Búfer de 200km')
ax.set_title('Búfer de 200km alrededor de Madrid')
ax.set_axis_off()
plt.legend()
plt.show()
🤝 Uniones Geométricas (union)
Combina dos o más geometrías en una sola. Útil para fusionar países adyacentes o crear regiones. Por ejemplo, podemos unir Portugal y España para formar la península ibérica.
iberian_peninsula = euro_countries_4326[euro_countries_4326['name'].isin(['Spain', 'Portugal'])]
# Unir las geometrías de España y Portugal
united_iberia = iberian_peninsula.unary_union # O .union_all()
fig, ax = plt.subplots(1, 1, figsize=(8, 8))
# Plotear la península ibérica unida
gpd.GeoSeries([united_iberia], crs='EPSG:4326').plot(ax=ax, color='orange', edgecolor='black')
ax.set_title('Península Ibérica Unida')
ax.set_axis_off()
plt.show()
💡 Consejos y Buenas Prácticas
- Consistencia de CRS: Siempre verifica y, si es necesario, reproyecta tus datos a un CRS consistente antes de realizar operaciones espaciales entre ellos. ¡Es la causa más común de errores!
- Rendimiento: Para grandes conjuntos de datos, las operaciones espaciales pueden ser costosas. Considera usar índices espaciales (
rtree) o simplificar geometrías si la precisión extrema no es necesaria (simplify()). - Fuentes de Datos: Explora otras fuentes de datos geoespaciales como OpenStreetMap (vía
osmnx), datos del INE, shapefiles gubernamentales, etc. - Visualización Interactiva: Para mapas web o interactivos, considera
Folium,Plotly ExpressohvPlotque se integran bien con GeoPandas.
❓ Preguntas Frecuentes (FAQ)
¿Qué diferencia hay entre GeoPandas y otras librerías SIG como QGIS o ArcGIS?
GeoPandas es una librería de Python para programación y análisis geoespacial, ideal para automatización y análisis complejos dentro de un script. QGIS y ArcGIS son aplicaciones de escritorio SIG con interfaces gráficas completas, excelentes para edición, visualización interactiva y tareas de mapeo general. GeoPandas complementa estas herramientas, permitiendo a los usuarios de Python extender sus capacidades.¿Puedo leer otros formatos de archivos además de Shapefiles y GeoJSON?
Sí, GeoPandas (a través de Fiona) puede leer una amplia variedad de formatos vectoriales geoespaciales como KML, GPX, ESRI File Geodatabase, PostGIS, etc. Solo necesitas especificar la ruta al archivo. Si el formato no se carga directamente, asegúrate de tener las dependencias de GDAL/OGR necesarias instaladas.¿Cómo manejo geometrías inválidas?
Las geometrías inválidas (por ejemplo, polígonos que se auto-interceptan) pueden causar problemas en operaciones espaciales. Shapely tiene un método `.is_valid` para comprobar la validez y `.buffer(0)` o `.make_valid()` (disponible en versiones recientes de Shapely) para intentar reparar geometrías inválidas.🎯 Conclusión
GeoPandas es una herramienta increíblemente poderosa para cualquier persona que necesite trabajar con datos geoespaciales en Python. Desde la carga y manipulación básica hasta la creación de mapas temáticos sofisticados y la realización de análisis espaciales complejos, ofrece una suite completa de funcionalidades. Dominar GeoPandas abre un mundo de posibilidades para entender y visualizar la información en su contexto geográfico, permitiéndote tomar decisiones más informadas y comunicar tus hallazgos de manera efectiva.
¡Anímate a explorar tus propios conjuntos de datos y a descubrir las historias que el espacio tiene para contar!
Tutoriales relacionados
- Concurrencia en Python: Ejecuta Tareas en Paralelo con `threading` y `multiprocessing`intermediate20 min
- Gestiona Archivos y Directorios con el Módulo `os` en Python: Una Guía Prácticaintermediate25 min
- Aprende a Manipular Imágenes con Pillow en Python: Una Guía para Procesamiento Digitalbeginner15 min
- Explora el Cosmos con Python: Una Guía de Web Scraping para Recopilar Datos Astronómicosintermediate15 min
- Interactúa con la Web: Guía para Procesar Formularios HTML con Flask y Pythonbeginner20 min
Comentarios (0)
Aún no hay comentarios. ¡Sé el primero!