| name | geopandas |
| description | Use when "GeoPandas", "geospatial", "GIS", "shapefile", "GeoJSON", or asking about "spatial analysis", "coordinate transformation", "spatial join", "choropleth map", "buffer analysis", "geographic data", "map visualization" |
| version | 1.0.0 |
GeoPandas Geospatial Data Analysis
Python library for geospatial vector data - extends pandas with spatial operations.
When to Use
- Working with geographic/spatial data (shapefiles, GeoJSON, GeoPackage)
- Spatial analysis (buffer, intersection, spatial joins)
- Coordinate transformations and projections
- Creating choropleth maps
- Processing geographic boundaries, points, lines, polygons
Quick Start
import geopandas as gpd
gdf = gpd.read_file("data.geojson")
print(gdf.head())
print(gdf.crs)
print(gdf.geometry.geom_type)
gdf.plot()
gdf_projected = gdf.to_crs("EPSG:3857")
gdf_projected['area'] = gdf_projected.geometry.area
gdf.to_file("output.gpkg")
Reading/Writing Data
gdf = gpd.read_file("data.shp")
gdf = gpd.read_file("data.geojson")
gdf = gpd.read_file("data.gpkg")
gdf = gpd.read_file("data.gpkg", bbox=(xmin, ymin, xmax, ymax))
gdf.to_file("output.gpkg")
gdf.to_file("output.geojson", driver="GeoJSON")
from sqlalchemy import create_engine
engine = create_engine("postgresql://user:pass@localhost/db")
gdf = gpd.read_postgis("SELECT * FROM table", con=engine, geom_col='geom')
Coordinate Reference Systems
print(gdf.crs)
gdf = gdf.set_crs("EPSG:4326")
gdf_projected = gdf.to_crs("EPSG:3857")
gdf_projected = gdf.to_crs("EPSG:32633")
Geometric Operations
buffered = gdf.geometry.buffer(100)
centroids = gdf.geometry.centroid
simplified = gdf.geometry.simplify(tolerance=5, preserve_topology=True)
hull = gdf.geometry.convex_hull
boundary = gdf.geometry.boundary
gdf['area'] = gdf.geometry.area
gdf['length'] = gdf.geometry.length
Spatial Analysis
Spatial Joins
joined = gpd.sjoin(gdf1, gdf2, predicate='intersects')
joined = gpd.sjoin(gdf1, gdf2, predicate='within')
joined = gpd.sjoin(gdf1, gdf2, predicate='contains')
nearest = gpd.sjoin_nearest(gdf1, gdf2, max_distance=1000)
Overlay Operations
intersection = gpd.overlay(gdf1, gdf2, how='intersection')
union = gpd.overlay(gdf1, gdf2, how='union')
difference = gpd.overlay(gdf1, gdf2, how='difference')
Dissolve (Aggregate by Attribute)
dissolved = gdf.dissolve(by='region', aggfunc='sum')
Clip
clipped = gpd.clip(gdf, boundary_gdf)
Visualization
import matplotlib.pyplot as plt
gdf.plot()
gdf.plot(column='population', cmap='YlOrRd', legend=True)
fig, ax = plt.subplots(figsize=(10, 10))
gdf1.plot(ax=ax, color='blue', alpha=0.5)
gdf2.plot(ax=ax, color='red', alpha=0.5)
plt.savefig('map.png', dpi=300, bbox_inches='tight')
gdf.explore(column='population', legend=True)
Common Workflows
Spatial Join and Aggregate
points_in_polygons = gpd.sjoin(points_gdf, polygons_gdf, predicate='within')
aggregated = points_in_polygons.groupby('index_right').agg({
'value': 'sum',
'count': 'size'
})
result = polygons_gdf.merge(aggregated, left_index=True, right_index=True)
Buffer Analysis
gdf_projected = points_gdf.to_crs("EPSG:3857")
gdf_projected['buffer'] = gdf_projected.geometry.buffer(1000)
gdf_projected = gdf_projected.set_geometry('buffer')
within_buffer = gpd.sjoin(other_gdf, gdf_projected, predicate='within')
Best Practices
- Always check CRS before spatial operations
- Use projected CRS for area/distance calculations
- Match CRS before spatial joins or overlays
- Validate geometries with
.is_valid before operations
- Use GeoPackage format over Shapefile (modern, better)
- Use
.copy() when modifying geometry to avoid side effects
- Filter during read with
bbox for large files
vs Alternatives
| Tool | Best For |
|---|
| GeoPandas | Vector data analysis, spatial operations |
| Rasterio | Raster data (satellite imagery, DEMs) |
| Shapely | Low-level geometry operations |
| Folium | Interactive web maps |
Resources