Delightful Figures in Python Series: Plotting Geographical Maps
By: Brinnae Bent
Tags: Data Visualization, Maps, Data Science, Data Analysis

With all of the election maps we have seen this week in the US, I thought it was time to release the next edition of Delightful Figures in Python with — you guessed it — plotting maps in Python!

I wanted to put together a series to guide Python-ers through generating delightful figures. Delightful figures can help you effectively tell your story, add credibility to your data analysis, and give your papers/articles/blogs a pop of fun. In Part 1 of the series, we focused on Donut Plots and in Part 2 of the series we created Word Clouds.

Getting Started

Some basic assumptions before we get started: I am assuming you have, at minimum, a basic understanding of python and you have a working knowledge of pandas, numpy, and matplotlib.

The dataset

This tutorial is BYODS (Bring your own data set), but if you want to follow along with the dataset I am using, I am using the Kaggle UFO sightings dataset, available here.

Make sure you have imported pandas, numpy, and matplotlib (including Basemap) before starting:

If you are following along with the UFO dataset, the first few lines of the dataframe should look like this:

Today I am interested in discovering the locations of Reported UFO Sightings. For mapping the data, I am most interested in the ‘latitude’ and ‘longitude’ columns. Key tip: always check the names of your columns before starting with data.columns(). If you are following along with the UFO dataset, note the extra space in the longitude column name!

Formatting our data for the map

We are going to pull the latitude and longitude columns into their own dataframe. If your datset is clean, feel free to skip this step. There are some strange, non-latitude/longitude values in the UFO dataset that we will want to remove before visualizing the data. We also want to convert our latitude and longitude to numeric values. By using the argument error=’coerce’, we are able to convert any wonky objects in the columns to NaN and subsequently remove them from our dataframe:

Building the map- step by step

We will start by setting the figure size and font size for our map.

Next, we will draw the projection with Basemap. Feel free to play with the arguments to the Basemap function to get the look you want for the map. After drawing the map, I recommend drawing coast lines.

Now we will convert our latitude and longitude columns of our dataframe into numpy arrays.

Next, we will plot these arrays on top of our map projection (remember “x”=longitude and “y”=latitude). Add a title and show your plot!

Here is the full code:

Trying different projections

Now that you have created your first map in Python, get creative! There are a number of built-in projections offered in the Basemap functionality. You can find all of the different options here.

If you want a globe projection, try the orthographic projection. Also try playing around with the use of colors on your map. (Check out colors here!)You can do this with the fillcontinents function.

If you are interested in more of a spatially-correct projection, I also like the Mollweide projection:

Combining Filtering with Maps

Now that we know the basics, we can start experimenting with more complex problems. My data spans from 1998–2014, and I am most interested in exploring data from 2010–2014.

First, I will want to convert my datetime column into a datetime format using pandas to_datetime. Because I care mostly about year, I will also create a new column that extracts only the year from the datetime column.

Next, I can filter my data to only include data that has a year greater than or equal to 2010:

Now I will repeat the same code I used above to create the first plot. This time, using the filterdata.

Here is the result, a plot of UFO Sightings from 2010–2014: