Embedding Maps with Python & Plotly

December 18, 2017
Written by
Lesley Cordero
Contributor
Opinions expressed by Twilio contributors are their own

plot_from_API_(15)

Data Visualization is an art form. Whether it be a simple line graph or complex objects like wordclouds or sunbursts, there are countless tools across different programming languages and platforms. The field of geospatial analysis is no exception. In this tutorial we’ll build a map visualization of the United States Electoral College using Python’s plotly module and a Jupyter Notebook.

Python Visualization Environment Setup

This guide was written in Python 3.6. If you haven’t already, download Python and Pip. Next, you’ll need to install the plotly module that we’ll use throughout this tutorial. You can do this by running the following in the terminal or command prompt on your operating system:

pip3 install plotly==2.0.9
pip3 install jupyter==1.0.0

Since we’ll be working with Python interactively, using the Jupyter Notebook is the best way to get the most out of this tutorial. You installed it with pip3 above and now you just need to get it running. Open up your terminal or command prompt and run the following command:

jupyter notebook

And BOOM! It should have opened up in your default browser.

A Quick Note on Jupyter

For those of you who are unfamiliar with Jupyter Notebook, I’ve provided a brief review of which functions will be particularly useful to move along with this tutorial.

In the image below you’ll see buttons labeled 1-3 that will be important for you to get a grasp of:

  1. Save button
  2. Add cell button
  3. Run cell button

Jupyter Notebook button descriptions

The first button is the button you’ll use to save your work as you go along (1). I won’t give you directions as when you should do this — that’s up to you!

Next, we have the add cell button (2). Cells are blocks of code that you can run together. These are the building blocks of Jupyter Notebook because it provides the option of running code incrementally without having to to run all your code at once.  Throughout this tutorial, you’ll see lines of code blocked off — each one should correspond to a cell.

Lastly, there’s the run cell button (3). Jupyter Notebook doesn’t automatically run your code for you; you have to tell it when by clicking this button. As with add button, once you’ve written each block of code in this tutorial onto your cell, you should then run it to see the output (if any). If any output is expected, note that it will also be shown in this tutorial so you know what to expect. Make sure to run your code as you go along because many blocks of code in this tutorial rely on previous cells.

Setting Up Plotly

In order to use Plotly, you’ll need an account with your own API key. Click here to set up an account with Facebook, Twitter, GitHub, Google Plus or your email address.

Plotly create a new account screen

Once you’ve logged in, look for your username in the upper right corner of the page. If you hover over it, four options pop up in a rectangular box. Select the Settings option, highlighted in the picture below:

Plotly changing settings example

This will redirect you to your settings page, where you’ll find six options. Next choose API Keys, highlighted in the image below:

Plotly API Key menu item

Finally, you have the page with all the needed information for this tutorial! In the image below, you’ll see two text boxes: one with your username and the other with your API key. These are the pieces of information you should store somewhere safely. The text in the API key should be protected, but since this is your first time using Plotly, you can go ahead and click the Regenerate Key button circled below. Copy and paste your username and API key somewhere safe for later.

Save your Plotly API Key

Formatting Data in Plotly

First, as always, we import the needed modules. Then we initialize our session by signing into Plotly, using the username and API key we just got.

import plotly.plotly as py
from plotly.graph_objs import *
py.sign_in('YOUR_USERNAME', 'YOUR_PASSWORD')

Plotly supports three types of maps: choropleths, atlas maps, and satellite maps. Using data from the electoral college, we’ll plot a choropleth map of the United States with a color scale. The darker the color, the greater number of votes.

First, we load in the electoral college data. Each number in the list of votes will correspond to a state label, which we’ll incorporate soon.

data = Data([
    Choropleth(
        z=[3.0, 3.0, 3.0, 3.0, 3.0, 3.0, 3.0, 3.0, 4.0, 4.0, 4.0, 4.0, 4.0, 5.0, 5.0, 5.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 7.0, 7.0, 7.0, 8.0, 8.0, 9.0, 9.0, 9.0, 10.0, 10.0, 10.0, 10.0, 11.0, 11.0, 11.0, 11.0, 12.0, 13.0, 14.0, 15.0, 16.0, 16.0, 18.0, 20.0, 20.0, 29.0, 29.0, 38.0, 55.0],
        autocolorscale=False,
        colorbar=ColorBar(
            title='Votes'
        ),

In the same ‘Data’ call, we include parameters that will be our sliding scale. This determines how light or dark a given state will be.

colorscale=[[0.0, 'rgb(242,240,247)'], [0.2, 'rgb(218,218,235)'], [0.4, 'rgb(188,189,220)'], [0.6, 'rgb(158,154,200)'], [0.8, 'rgb(117,107,177)'], [1.0, 'rgb(84,39,143)']],
    hoverinfo='location z',

Now we’re ready to add labels for each state, making sure to keep the order in place so that states aren’t mislabeled.

locationmode='USA-states',
        locations=['DE', 'VT', 'ND', 'SD', 'MT', 'WY', 'AK', 'DC', 'NH', 'RI', 'ME', 'ID', 'HI', 'WV', 'NE', 'NM', 'MS', 'AR', 'IA', 'KS', 'NV', 'UT', 'CT', 'OR', 'OK', 'KY', 'LA', 'SC', 'AL', 'CO', 'MD', 'MO', 'WI', 'MN', 'MA', 'TN', 'IN', 'AZ', 'WA', 'VA', 'NJ', 'NC', 'GA', 'MI', 'OH', 'PA', 'IL', 'NY', 'FL', 'TX', 'CA'],
        marker=Marker(
            line=Line(
                color='rgb(255,255,255)',
                width=2
            )
        ),
        text=['DE', 'VT', 'ND', 'SD', 'MT', 'WY', 'AK', 'DC', 'NH', 'RI', 'ME', 'ID', 'HI', 'WV', 'NE', 'NM', 'MS', 'AR', 'IA', 'KS', 'NV', 'UT', 'CT', 'OR', 'OK', 'KY', 'LA', 'SC', 'AL', 'CO', 'MD', 'MO', 'WI', 'MN', 'MA', 'TN', 'IN', 'AZ', 'WA', 'VA', 'NJ', 'NC', 'GA', 'MI', 'OH', 'PA', 'IL', 'NY', 'FL', 'TX', 'CA']
    )
])

Altogether, we have:

In [ ]:
data = Data([
    Choropleth(
        z=[3.0, 3.0, 3.0, 3.0, 3.0, 3.0, 3.0, 3.0, 4.0, 4.0, 4.0, 4.0, 4.0, 5.0, 5.0, 5.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 7.0, 7.0, 7.0, 8.0, 8.0, 9.0, 9.0, 9.0, 10.0, 10.0, 10.0, 10.0, 11.0, 11.0, 11.0, 11.0, 12.0, 13.0, 14.0, 15.0, 16.0, 16.0, 18.0, 20.0, 20.0, 29.0, 29.0, 38.0, 55.0],
        autocolorscale=False,
        colorbar=ColorBar(
            title='Votes'
        ),
        colorscale=[[0.0, 'rgb(242,240,247)'], [0.2, 'rgb(218,218,235)'], [0.4, 'rgb(188,189,220)'], [0.6, 'rgb(158,154,200)'], [0.8, 'rgb(117,107,177)'], [1.0, 'rgb(84,39,143)']],
        hoverinfo='location+z',
        locationmode='USA-states',
        locations=['DE', 'VT', 'ND', 'SD', 'MT', 'WY', 'AK', 'DC', 'NH', 'RI', 'ME', 'ID', 'HI', 'WV', 'NE', 'NM', 'MS', 'AR', 'IA', 'KS', 'NV', 'UT', 'CT', 'OR', 'OK', 'KY', 'LA', 'SC', 'AL', 'CO', 'MD', 'MO', 'WI', 'MN', 'MA', 'TN', 'IN', 'AZ', 'WA', 'VA', 'NJ', 'NC', 'GA', 'MI', 'OH', 'PA', 'IL', 'NY', 'FL', 'TX', 'CA'],
        marker=Marker(
            line=Line(
                color='rgb(255,255,255)',
                width=2
            )
        ),
        text=['DE', 'VT', 'ND', 'SD', 'MT', 'WY', 'AK', 'DC', 'NH', 'RI', 'ME', 'ID', 'HI', 'WV', 'NE', 'NM', 'MS', 'AR', 'IA', 'KS', 'NV', 'UT', 'CT', 'OR', 'OK', 'KY', 'LA', 'SC', 'AL', 'CO', 'MD', 'MO', 'WI', 'MN', 'MA', 'TN', 'IN', 'AZ', 'WA', 'VA', 'NJ', 'NC', 'GA', 'MI', 'OH', 'PA', 'IL', 'NY', 'FL', 'TX', 'CA']
    )
])

Now we’ve formatted our data. But of course, our code needs to know how to display this data. Luckily, we can just use plotly‘s  Layout class. We’ll pass in color schemes and labels as parameters.

layout = Layout(
    geo=dict(
        lakecolor='rgb(255, 255, 255)',
        projection=dict(
            type='albers usa'
        ),
        scope='usa',
        showlakes=True
    ),
    title='2016 Electoral College Votes'
)

Displaying the Plotly Map

We’re almost done! The last step is to construct the map and use plotly to actually display it.

fig = Figure(data=data, layout=layout)
plot_url = py.plot(fig)

This should open up a link in your browser with our visualization on display. It should look like the following:

Plotly visualization example colorized from Python

(You can also see my version of the visualization here.)

Now that we’ve generated our map on the Plotly website, let’s explore the different display options available. Take a look at the upper right corner of the visualization. You’ll notice a camera icon, which if you hover over says, “Download plot as a png.” This image allows you to download a static picture of your visualization, which you can then embed as you would any other photo.

Next, scroll to the bottom of the page. Notice the 5 icons on the lower right corner: Facebook, Google Plus, and Twitter logos, followed by a chain link graphic and “”. Click on that final one, “”.

Button to embed a Plotly visualization

It should have opened a modal that looks like this:

Plotly embed dialog

Now you can copy and paste that html snippet in any HTML file, and it will elegantly display the visualization. For example, the embed markup for my graph looks like this:

<div>
    <a href="https://plot.ly/~lc2958/36/" target="_blank" title="plot from API (15)" style="display: block; text-align: center;"><img src="https://plot.ly/~lc2958/36.png" alt="plot from API (15)" style="max-width: 100%;width: 600px;"  width="600" onerror="this.onerror=null;this.src='https://plot.ly/404.png';" /></a>
    <script data-plotly="lc2958:36" src="https://plot.ly/embed.js" async></script>
</div>

plotly is a useful Python module for displaying almost any type of data, whether that be numerical, text, or geospatial. In this tutorial, we focused on geospatial mapping, but if you’re interested in expanding your visualization toolkit, you can look here for more ideas.

If you liked what you did here, check out my GitHub (@lesley2958) and Twitter (@lesleyclovesyou) for more content!