Why you should be using GeoPandas in Python to Visualize Data on Maps (aka Geo-Visualization)
By: Nick Minaie
Tags: Visualization, Data Science, Python, Maps, Machine Learning

Data visualization is one of the most important steps in presenting data in a project, whether it is to your team, your managers, or your clients or stakeholders. Data visualization is also a critical element of Exploratory Data Analysis (EDA), and can save you a lot of time in a project.

According to SaS:

“Data visualization is the presentation of data in a pictorial or graphical format. It enables decision makers to see analytics presented visually, so they can grasp difficult concepts or identify new patterns. With interactive visualization, you can take the concept a step further by using technology to drill down into charts and graphs for more detail, interactively changing what data you see and how it’s processed.”

Visualizing NCAA College Football Fans on the US Map (https://www.nytimes.com/interactive/2014/10/03/upshot/ncaa-football-fan-map.html)

But why does data visualization matter?

In an article on the Search Engine Journal, Adam Heitzman says, “We are an inherently visual world, where images speak louder than words. Data visualization is especially important when it comes to big data and data analyzation projects.”

With massive amount of data the is generated every day, data visualization has become important more than ever to tell the story, and to help in getting insight about data, as opposed to looking over pages and pages of tabular data; a task that may seem daunting in many cases, or even impossible in some cases. Adam Heitzman, in the same article mentions, “The results from complex algorithms are much easier to understand in a visual format as opposed to lines and lines of text and numbers.”

GeoPandas for Data Visualization: Geo-Visualization

GeoPandas documentation is a great resource for learning about this powerful library. The site mentions:

“GeoPandas is an open source project to make working with geospatial data in python easier. GeoPandas extends the datatypes used by pandas to allow spatial operations on geometric types. Geometric operations are performed by shapely. Geopandas further depends on fiona for file access and descartes and matplotlib for plotting… GeoPandas enables you to easily do operations in python that would otherwise require a spatial database such as PostGIS.”

How does GeoPandas work in Jupyter Notebook?

First you need to install geopandas in your Jupyter Notebook using pip :

!pip install geopandas

geopandas.org gives you a warning that geopandas must be installed along with all required dependences. To ensure better functionality, especially for plotting, other dependencies are suggested, as below:

Required dependencies:

numpy

pandas (version 0.19.1 or later)

shapely (interface to GEOS)

fiona (interface to GDAL)

pyproj (interface to PROJ)

six

Further, optional dependencies are:

rtree (optional; spatial index to improve performance and required for overlay operations; interface to libspatialindex)

psycopg2 (optional; for PostGIS connection)

geopy (optional; for geocoding)

For plotting, these additional packages may be used:

import pandas as pd

import geopandas as gpd # importing geopandas

import matplotlib.pyplot as plt

The example outlined in this article works with a shape file ( .shx format ) that can be downloaded from www.arcgis.com . The code below refers to the relative path for the file assuming it is in the working directory. It should be noted that you will need all related files in the same directory for the .shx file to load properly. These files are listed below.

Files associated with .shx shape file

file_path = './states.shx' . # reference to the file path map_us = gpd.read_file(file_path) map_us.head()

This should import the data and store it in the map_us DataFrame. Using .head method on this, we can see the columns and the first five rows.

We should first check the data types in the DataFrame.

map_us.dtypes STATE_NAME object

DRAWSEQ int64

STATE_FIPS object

SUB_REGION object

STATE_ABBR object

geometry object

dtype: object

The first column STATE_NAME is the name of the state, and the second column, DRAWSEQ is the sequence of drawing on the plot. For example, the plot will draw Hawaii first and then then Washington, Montana, and so on.

The next column is STATE-FIPS columns, which stands for State Federal Information Processing Standard (FIPS) code. According to Wikipedia,

“FIPS Codes were numeric and two-letter alphabetic codes defined in U.S. Federal Information Processing Standard Publication (“FIPS PUB”) 5–2 to identify U.S. states and certain other associated areas.”

SUB_REGION is the next column, and includes the nine sub-regions in the US. You can get the list as below. This column is followed by STATE_ABR column which includes the two character abbreviations for the states.

map_us['SUB_REGION'].unique array(['Pacific', 'Mountain', 'New England', 'West North Central',

'East North Central', 'Middle Atlantic', 'South Atlantic',

'East South Central', 'West South Central'], dtype=object)

But what sets geopandas apart from pandas is the geometry column that includes the details of state (or any city, county, region, country, etc.) border. This column is known to geopandas and would not work in pandas . To illustration below show how this works:

Plotting Washington State using ‘geometry’ Column in the Map GeoPandas DataFrame

Next if defining our data, and what state we want to plot (or not). We can do this using any of the columns. For example, using DRAWSEQ is used below to filter the data:

map_us[(map_df['DRAWSEQ']<51) & (map_df['DRAWSEQ']>=2)]

One we have the data, we can plot the map:

# Creating a subplot, with 'fig' and 'ax'

fig, ax = plt.subplots(1, figsize=(15, 8)) # Sending the filtered dat to plot

plt.title('Map of the United States Sub-Regions', size=16)

map_us[(map_us['DRAWSEQ']<51) & (map_us['DRAWSEQ']>=2)].plot(column='SUB_REGION', cmap='Greens', # Colormap for the states

linewidth=0.4, # line width for state borders

ax=ax, # plotting the map on 'ax'

edgecolor='black'); # State border colors

And here is the map:

You can customize the map by adding, for example, a color bar:

c_bar_colors = plt.cm.ScalarMappable(cmap='Greens', norm=plt.Normalize(vmin=map_us['DRAWSEQ'].min(), vmax=map_us['DRAWSEQ'].max())) # Plotting the colorbar

color_bar = fig.colorbar(c_bar_colors)

More customization possible? Of course! You can use your creativity and add state names to the map, or plot other information.

How can this map be used to visualize some data, say ‘US Median Household Income’?

First you need to import your data into a DataFrame, and then clean your data, and format your DataFrame so it has a state column, plus the other columns you want to visualize. One you have that, you can then merge that DataFrame with your map GeoPandas DataFrame using the state column.

Note: You should always add your Pandas DataFrame to your GeoPandas DataFrame, and not the other way around.

merged_map_df = pd.merge(map_us, other_df, on='state')

Then you can simply replace SUB_REGION in the code above with the column you want to visualize. For example, if we added 2018_sat_participation data to our map_df and called it merge_map_df :

plt.title('Map of the United States Sub-Regions', size=16) merged_map_df.plot(column='2018_sat_participation', cmap='Greens', # Colormap for the states

linewidth=0.4, # line width for state borders

ax=ax, # plotting the map on 'ax'

edgecolor='black'); # State border colors

Visualizing ‘2018 SAT Participation` Data on the US Map

Plotting US County-Level Maps

Using the same technique, we can plot any other maps, as long as we have the shape file. For example, the shape file for the US counties, can be downloaded from the www.data.gov website.

Have Fun, Mapping!

There is really no limit in what you can do with GeoPandas coupled with other Python libraries.