Skip to content

Python for GIS

Goal: Use Python to automate GIS workflows — the single most valuable skill upgrade you can make as a GIS analyst.

What you'll learn

  • Why Python matters in GIS
  • The two main libraries: arcpy (ArcGIS) and geopandas (open source)
  • Common automation patterns
  • How to integrate Python in ArcGIS Pro

Why Python?

You'll do the same workflow over and over. Buffer 47 layers. Clip 200 raster tiles. Run weekly reports. Python turns 4-hour clicking sessions into 30-second scripts.

flowchart LR
    A[Manual workflow<br/>30 layers × 4 tools = 120 clicks] --> B((Python))
    B --> C[Automated workflow<br/>1 script, runs unattended]

    classDef m fill:#fef2f2,stroke:#ef4444,color:#991b1b
    classDef a fill:#dcfce7,stroke:#10b981,color:#065f46
    class A m
    class C a

The two main paths

Library Where it runs Pro / Con
arcpy Inside ArcGIS Pro's Python ✅ Full Pro toolset, ✅ enterprise integration. ❌ Windows only, ❌ requires Pro license.
geopandas Anywhere Python runs ✅ Free, ✅ works on Mac/Linux, ✅ pandas API. ❌ smaller toolset, slower for huge data.

You'll use both. arcpy for production work in ArcGIS-shop jobs, geopandas for prototyping, education, and open-source pipelines.

Python primer (1 minute)

If Python is new to you, here's the bare minimum:

from pathlib import Path

cities = ["Atlanta", "Athens", "Augusta"]

for city in cities:
    print(f"Processing {city}...")
    out = Path("data") / f"{city.lower()}.shp"
    print(out)

Variables, lists, loops, f-strings, paths. That's 80% of GIS scripting.

arcpy: the ArcGIS Pro library

Open ArcGIS Pro → View → Python window.

import arcpy

arcpy.env.workspace = r"C:\projects\atlanta\data.gdb"
arcpy.env.overwriteOutput = True

arcpy.analysis.Buffer(
    in_features="schools",
    out_feature_class="schools_500m",
    buffer_distance_or_field="500 Meters"
)

arcpy.analysis.Clip(
    in_features="streets",
    clip_features="county",
    out_feature_class="streets_county"
)

Every tool in the Geoprocessing pane has a Python equivalent. You can copy a tool's command from the History pane.

Looping through layers

import arcpy

arcpy.env.workspace = r"C:\projects\atlanta\data.gdb"

for fc in arcpy.ListFeatureClasses("*_streets"):
    out = f"{fc}_buffer"
    arcpy.analysis.Buffer(fc, out, "100 Feet")
    print(f"Buffered {fc}")

That's where the magic starts.

geopandas: the open-source way

import geopandas as gpd

# Read
counties = gpd.read_file("counties.shp")
schools = gpd.read_file("schools.geojson")

# Reproject
counties = counties.to_crs(epsg=2240)
schools = schools.to_crs(epsg=2240)

# Buffer
school_buffers = schools.copy()
school_buffers["geometry"] = schools.buffer(500)

# Spatial join
counties_with_school_count = gpd.sjoin(
    counties,
    schools,
    how="left",
    predicate="contains"
)

# Save
counties_with_school_count.to_file("counties_schools.gpkg", driver="GPKG")

Notice how concise it is. GeoPandas is a pandas DataFrame with a geometry column.

Other essential libraries

  • rasterio

    Read, write, and manipulate raster data. The raster equivalent of geopandas.

  • xarray + rioxarray

    Multi-dimensional rasters (time series, multi-band) — climate and remote sensing.

  • shapely

    Pure-geometry operations (intersect, buffer, contains).

  • pyproj

    CRS transformations and projection math.

  • fiona

    Low-level vector I/O (powers geopandas).

  • folium / pydeck

    Interactive maps directly from Python notebooks.

Common automation patterns

Batch reproject

import geopandas as gpd
from pathlib import Path

for shp in Path("input").glob("*.shp"):
    gdf = gpd.read_file(shp).to_crs(epsg=2240)
    gdf.to_file(Path("output") / shp.name)

Generate weekly report

import arcpy
import datetime

today = datetime.date.today().isoformat()
out = f"reports/weekly_{today}.pdf"

aprx = arcpy.mp.ArcGISProject("CURRENT")
layout = aprx.listLayouts("Weekly Report")[0]
layout.exportToPDF(out, resolution=300)
print(f"Saved {out}")

Filter, buffer, summarize

import geopandas as gpd

stops = gpd.read_file("transit_stops.shp").to_crs(2240)
tracts = gpd.read_file("tracts.shp").to_crs(2240)

stops_buffer = stops.buffer(800).unary_union  # ~half-mile
near_transit = tracts[tracts.intersects(stops_buffer)]
print(f"{len(near_transit)} of {len(tracts)} tracts are within walking distance.")

Notebooks in ArcGIS Pro

ArcGIS Pro has integrated Jupyter notebooks. Insert → Notebook. Use them for:

  • Documenting analysis (text + code + map exports)
  • Iterating without losing your project
  • Sharing reproducible workflows

Where to learn the syntax


Practice

First scripting project

  1. Take a workflow you do manually (e.g., buffer + clip + export).
  2. Run it once in ArcGIS Pro.
  3. Open the Geoprocessing History, right-click each step → Copy Python Snippet.
  4. Paste them into a .py file and run it.
  5. Then turn the inputs into a loop over multiple layers.

That's automation in 30 minutes.


Next up

SQL for GIS — query language for attribute tables and spatial databases.