Python GIS
Made Practical
Hands-on guides for working with spatial data in Python. GeoPandas, coordinate reference systems, spatial joins, rasterio — clear answers to real problems.
Built for anyone working with maps and spatial data in Python — from first install to production-ready GIS workflows.
- 389 guides
- 18 learning paths
- 90 error fixes
- 3+ diagrams per guide
What You'll Find Here
Practical & Direct
Every guide starts with the problem and delivers a quick answer, then walks through a step-by-step solution with real Python code. No filler, no detours.
Python-First
All content uses GeoPandas, Shapely, Rasterio, Fiona, and the wider Python GIS ecosystem. Code snippets you can copy and run today.
Beginner-Friendly
Whether you're opening your first shapefile or debugging a spatial join, guides are written for clarity — no GIS PhD required.
Browse by Topic
Every subject on the site. Each topic page gathers the concepts, the how-to guides and the fixes for that subject in one place.
Fundamentals
What the objects, files and libraries actually are.
Geometry & space
The shapes themselves, where they sit on the earth, and how they relate.
Imagery & point clouds
Data that arrives as measurements of a surface rather than as features on it.
Analysis
Getting from a raw download to something you can put in front of someone.
Modelling & prediction
Predicting a value where nobody measured one — and knowing where that prediction stops meaning anything.
Production
Work that runs without you watching it.
Tools
The other software in a Python GIS stack, driven from Python.
Learning Paths
Curated, topic-based routes through the guides — start at the top of a path and work down.
-
Finding & Fetching Data
Get the data before you analyse it — from OSM, web services and satellite catalogues.
14 guides → -
Spatial Statistics
Measure the pattern instead of eyeballing the map.
13 guides → -
Terrain & Elevation
Turn a grid of heights into slope, shade, contours and drainage.
12 guides → -
Networks & Routing
Distance along the street, not across the rooftops.
11 guides → -
Raster Analysis
Read, reproject, clip and summarise raster data in Python.
14 guides → -
Spatial SQL & PostGIS
Move the heavy lifting from Python into the database.
15 guides → -
Making Maps
Turn a GeoDataFrame into a map someone else can read.
13 guides → -
GIS Data Cleaning
Turn messy spatial data into analysis-ready datasets.
33 guides → -
Batch Processing
Process many files at once, reliably.
26 guides → -
Automation & Pipelines
Build repeatable, config-driven GIS pipelines.
26 guides → -
QGIS Automation
Automate QGIS with PyQGIS and Processing models.
25 guides → -
Satellite Imagery
From a scene on a catalogue to a number you can defend.
16 guides → -
LiDAR & Point Clouds
Millions of points, and the surfaces worth deriving from them.
14 guides → -
Cloud-Native GIS
Read the part you need, not the file it lives in.
14 guides → -
Publishing Web Maps
Get the data into a browser without shipping the whole dataset.
15 guides → -
Movement & Time
Tracks are not points — the order and the clock are the data.
14 guides → -
Spatial Machine Learning
Why the usual rules break, and what to do instead.
14 guides → -
Interpolation & Surfaces
A continuous surface from scattered samples, with its support attached.
13 guides →
Concepts
Core concepts and essential knowledge for Python GIS.
- Extrapolation in Space Explained: The Area of Applicability area of applicability explained
- Attribute Join or Spatial Join? Choosing How to Combine Two Layers attribute join vs spatial join
- Cron, systemd, Airflow or CI? Choosing a Scheduler for GIS Jobs choosing a scheduler for python jobs
- IDW, Kriging, Splines or TIN? Choosing an Interpolator choosing an interpolator explained
- Choosing the Unit of Work in a Batch Job: File, Layer, Feature or Tile batch unit of work gis
- Choropleth Classification Explained: Quantiles, Equal Interval and Natural Breaks choropleth classification schemes
How-To Guides
Step-by-step solutions for common GIS tasks.
- How to Add a Basemap to a GeoPandas Map with contextily geopandas basemap contextily
- How to Aggregate Movement into Flows Between Zones aggregate movement flows python
- How to Animate Movement Over Time in Python animate movement python
- How to Interpolate to Polygons Instead of a Grid areal interpolation python
- How to Assert on Geometry in pytest Without Flaky Comparisons pytest assert geometry equal
- How to Batch-Generate a Map Image for Every Region in Python batch generate maps python
- How to Build Spatial Features for a Machine Learning Model build spatial features python
- How to Build a Street Network Graph in Python with OSMnx street network graph python
- How to Build Vector Tiles from a GeoDataFrame in Python build vector tiles python
Fixes
Diagnose and fix common Python GIS errors — installs and CRS problems, broken geometries and failed writes, batch jobs that stop, scheduled scripts that never run, and PyQGIS crashes.
- GeoJSON Downloaded from an API Is Empty or Truncated api geojson truncated
- Batch GIS Job Slows Down and Runs Out of Memory: How to Fix It batch job memory leak python
- Batch Job Gives Different Results Each Run: How to Fix It gis batch non deterministic output
- Batch Output Files Keep Overwriting Each Other: How to Fix It batch output files overwriting
- Batch Script Stops at the First Bad File: How to Keep It Running batch script stops on error
- buffer(0) Does Not Fix My Invalid Geometry: What to Do Instead buffer 0 not fixing geometry
- Cannot Transform Naive Geometries to CRS: How to Fix It in GeoPandas cannot transform naive geometries
- GIS Tests Run Out of Memory or Time Out in CI: How to Fix It ci out of memory gis tests
- My Cleaned Layer Has More Rows Than the Original: How to Fix It geopandas more rows after cleaning