Photo by Denise Jans on Unsplash

Geopandas: Accessible, Yet Powerful GIS With Python

The Basics

>>> pip install geopandas
>>> pip install descartes
>>> import geopandas
>>> import matplotlib.pyplot as plt
# GeoPandas comes with a few toy GeoDataFrames:
>>> geopandas.datasets.available
['naturalearth_lowres', 'naturalearth_cities', 'nybb']
>>> world = geopandas.read_file(geopandas.datasets.get_path('naturalearth_lowres'))>>> world.head()
png
>>> ax = world.plot(column='pop_est',
cmap='Spectral',
figsize=(15, 15),
edgecolor='white',
label='name',
legend=True,
legend_kwds={"label":"Population",
"orientation":"horizontal"
}
);

>>> ax.axis('off');
png
>>> world['geometry'][4]
Jupyter Notebook rendering of [‘geometry’].
>>> ax = world.plot(facecolor='none', edgecolor='black', figsize=(15,15));>>> cities  = geopandas.read_file(geopandas.datasets.get_path('naturalearth_cities'))>>> cities.plot(ax=ax, color='red', marker='o');>>> ax.axis('off');
png
Photo by Milan De Clercq on Unsplash

Relationship Between Geospatial Data

# Points
>>> london = cities.loc[cities['name']=='London', 'geometry'].squeeze()
>>> paris = cities.loc[cities['name']=='Paris', 'geometry'].squeeze()

#Polygons
>>> france = world.loc[world['name']=='France', 'geometry'].squeeze()
>>> uk = world.loc[world['name']=='United Kingdom', 'geometry'].squeeze()
>>> london.within(uk)
True
>>> uk.touches(france)
False
>>> uk.area
34.20295398919941
>>> london.distance(paris)
3.5968122687166146
>>> from shapely.geometry import LineString
>>> london_paris = LineString([london, paris])
>>> geopandas.GeoSeries([london, paris, london_paris, london.buffer(5), uk, france]).plot(figsize=(15,15), cmap='Spectral');

# Note how the london.buffer(5) "layer" is below the uk layer.
>>> plt.xlim(-10,10);
>>> plt.ylim(40, 60);
# axis limits are necessary because France includes French Guiana in this dataset (unlike some dataset which limit France to Metropolitan France)
png
>>> paris.within(london.buffer(5))
True
>>> london_paris.intersects(uk)
True
>>> london.buffer(5).difference(uk)
Spatial differences between a 5 degree buffer around London and the UK mainland.
Photo by Annie Spratt on Unsplash

Coordinate Reference System

>>> world.crs<Geographic 2D CRS: EPSG:4326>
Name: WGS 84
Axis Info [ellipsoidal]:
- Lat[north]: Geodetic latitude (degree)
- Lon[east]: Geodetic longitude (degree)
Area of Use:
- name: World
- bounds: (-180.0, -90.0, 180.0, 90.0)
Datum: World Geodetic System 1984
- Ellipsoid: WGS 84
- Prime Meridian: Greenwich
>>> world_utm = world.to_crs(epsg=23031)
>>> cities_utm = cities.to_crs(epsg=23031)
>>> world_utm.crs<Projected CRS: EPSG:23031>
Name: ED50 / UTM zone 31N
Axis Info [cartesian]:
- E[east]: Easting (metre)
- N[north]: Northing (metre)
Area of Use:
- name: Europe - 0°E to 6°E and ED50 by country
- bounds: (0.0, 38.56, 6.01, 82.41)
Coordinate Operation:
- name: UTM zone 31N
- method: Transverse Mercator
Datum: European Datum 1950
- Ellipsoid: International 1924
- Prime Meridian: Greenwich
# Points
>>> london_utm = cities_utm.loc[cities_utm['name']=='London', 'geometry'].squeeze()
>>> paris_utm = cities_utm.loc[cities_utm['name']=='Paris', 'geometry'].squeeze()
#Polygons
>>> france_utm = world_utm.loc[world_utm['name']=='France', 'geometry'].squeeze()
>>> uk_utm = world_utm.loc[world_utm['name']=='United Kingdom', 'geometry'].squeeze()
>>> print(f'London to Paris:{london_utm.distance(paris_utm) / 1_000 : .2f} kilometres')London to Paris: 341.10 kilometres
>>> print(f'UK area:{uk_utm.area / 1_000_000 : .2f} km²')UK area: 250757.98 km²
Photo by David Pennington on Unsplash

Spatial Join

>>> joined = geopandas.sjoin(cities, world, op='within', how='left')
png
>>> joined[joined['index_right'].isna()]
png
>>> joined[joined['index_right'].isna()].plot(ax=world.plot(column='continent', figsize=(15,15)), color='red');
>>> plt.xlim(20,180);
>>> plt.ylim(-20,20);
png

Last Words

Data Scientist

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store