Making a Leaflet map using Folium, GeoPandas, and Pandas

Folium reference: https://python-visualization.github.io/folium/quickstart.html#Getting-Started

Start by importing folium, pandas as pd, and geopandas as gpd, and os

In [34]:
import folium
import geopandas as gpd
import pandas as pd
import os

Set your working directory to the home folder

In [4]:
os.chdir('../../')

Add the TahoeTracts_geodata.geojson file created earlier to a new geodataframe named 'tahoeTracts'

Type:
>>> tahoeTracts = gpd.read_file('TahoeTracts_geodata.geojson')

In [5]:
tahoeTracts = gpd.read_file('TahoeTracts_geodata.geojson')

First, we'll make a very basic map without any layers:

Type:
>>> map = folium.Map()
>>> map

In [6]:
map = folium.Map()
map
Out[6]:

You made a map!

Now let's customize it by padding a few parameters...

Type:
>>> m = folium.Map(
location = [39.025, -120.032349],
tiles = 'Stamen Terrain',
zoom_start = 10
)
>>> m*

In [16]:
m = folium.Map(
    location = [39.025, -120.032349],
    tiles = 'Stamen Terrain',
    zoom_start = 9)
m
Out[16]:

Great. We changed the starting point, changed the basemap, and the zoom level.

Now let's add a data layer:

Type:
>>> m = folium.Map( location = [39.025, -120.032349], tiles = 'Stamen Terrain', zoom_start = 10 )

>>> folium.GeoJson(tahoeTracts).add_to(m)

>>> m

In [20]:
m = folium.Map(location = [39.025, -120.032349], tiles = 'Stamen Terrain', zoom_start = 10)

folium.GeoJson(tahoeTracts).add_to(m)

m
Out[20]:

Easy, right? Now let's change the layer styling.

Paste the above code into the following cell and make the following modifications:

>>> m = folium.Map(location = [39.025, -120.032349], tiles = 'Stamen Terrain', zoom_start = 10 )

>>> folium.GeoJson(tahoeTracts, style_function = lambda feature: {'fillColor': '#00ff00'}).add_to(m)

>>> m

In [22]:
m = folium.Map(location = [39.025, -120.032349], tiles = 'Stamen Terrain', zoom_start = 10 )

folium.GeoJson(tahoeTracts, style_function = lambda features: {'fillColor': '#00ff00'}).add_to(m)

m
Out[22]:

Cool!

To make this easier to read, you can add returns to those long, in-line code snippets, like so:

Type this out manually in the cell below:

>>>
m = folium.Map(
location = [39.025, -120.032349],
tiles = 'Stamen Terrain',
zoom_start = 10
)

>>>
folium.GeoJson(tahoeTracts,
style_function = lambda feature: {'fillColor': '#00ff00'}
).add_to(m)

>>> m

In [23]:
m = folium.Map(location = [39.025, -120.032349], 
               tiles = 'Stamen Terrain', 
               zoom_start = 10 )

folium.GeoJson(tahoeTracts, 
               style_function = lambda features: {'fillColor': '#00ff00'}
              ).add_to(m)

m
Out[23]:

Easier to read now? Good!

You can also move the style function to a variable, which will make make it easier to read and further customize.

Type:

>>>
style = lambda feature: {'fillColor': '#00ff00',
'color': 'Green', 'weight':2}

>>>
m = folium.Map(
location = [39.025, -120.032349],
tiles = 'Stamen Terrain',
zoom_start = 10
)

>>>
folium.GeoJson(tahoeTracts,
style_function = style
).add_to(m)

>>>m

In [27]:
style = lambda features: {'fillColor': '#00ff00',
                         'color':'Green', 'weight':2}


m = folium.Map(location = [39.025, -120.032349], 
               tiles = 'Stamen Terrain', 
               zoom_start = 10 )

folium.GeoJson(tahoeTracts, 
               style_function = style
              ).add_to(m)

m
Out[27]:

Go wild!

Now let's make a choropleth.

Folium offers folium.choropleth() as an easy method to make a choropleth.

This method takes a Pandas dataframe and joins it to a GeoJson on the fly to generate a choropleth.

If your GeoJson or shapefile layer already have attributes baked in that you want to display, you can use a more complex alternative method here: https://nbviewer.jupyter.org/github/python-visualization/folium/blob/master/examples/plugin-Search.ipynb

My way is kind of a hack!

We do have attributes baked in, but I want to use the easier folium.choropleth() method.

Q:What should we do if we need to add our choropleth data to our geodata, but our choropleth data is already part of our geodata?
A: Make a regular pandas dataframe out of our geodataframe, then add it back.

Yes, this is a hack!

Create a pandas dataframe from the tahoeTracts geodataframe:
Type:
>>> tractdata = pd.DataFrame(tahoeTracts)

In [28]:
tractdata = pd.DataFrame(tahoeTracts)

Now the attributes are in a separate dataframe.

Type the following:

>>>
m = folium.Map(
location = [39.025, -120.32349],
tiles = 'Stamen Terrain',
zoom_start = 10
)

>>>
folium.Choropleth(
geo_data = tahoeTracts,
data = tractdata,
columns = ['GEOID', 'Median Household Income (In 2017 Inflation Adjusted Dollars)'],
key_on = 'feature.properties.GEOID',
fill_color = 'RdYlGn',
fill_opacity = 0.7,
line_opacity = 0.5,
).add_to(m)

>>> m

In [44]:
m = folium.Map(location = [39.025, -120.032349],
              tiles = 'Stamen Terrain',
              zoom_start = 10)

folium.Choropleth(geo_data = tahoeTracts,
                 data = tractdata,
                 columns = ['GEOID', 'Median Household Income (In 2017 Inflation Adjusted Dollars)'],
                 key_on = 'feature.properties.GEOID',
                 fill_color = 'RdYlGn',
                 fill_opacity = 0.7,
                 line_opacity = 0.5,
                 ).add_to(m)

m
Out[44]:

Ta Da!!!! You made a webmap using code! That is cool!

Oh, you actually want to put that on the web? Easy!

Type:
m.save('my_map.html')

In [45]:
m.save('my_map.html')

Great Job! You're getting really good at this!