Python Webmapping with Folium¶
For this exercise we will use the following libraries:¶
>>> import pandas as pd
>>> import geopandas as gpd
>>> import folium
>>> import branca
>>> import os
Pandas/GeoPandas for reading geospatial data, Folium to generate the web map, Branca to create a colormap, and OS for system navigation as needed.
In [ ]:
import pandas as pd
import geopandas as gpd
import folium
import branca
import os
Now, create a map as m with folium.Map():¶
>>> m = folium.Map()
>>> m
In [2]:
m = folium.Map()
m
Out[2]:
Make this Notebook Trusted to load map: File -> Trust Notebook
There's your basic map. Now let's set the starting location to the Boulder area and change the basemap tiles:¶
>>> m = folium.Map(location = [40.1, -105.4], tiles = 'Stamen Terrain', zoom_start = 10)
>>> m
In [3]:
m = folium.Map(location = [40.1, -105.5], tiles = 'CartoDB Positron', zoom_start= 10)
m
Out[3]:
Make this Notebook Trusted to load map: File -> Trust Notebook
Now let's add a point to the map:¶
>>> m = folium.Map(location = [40.1, -105.4], tiles = 'Stamen Terrain', zoom_start = 10)
>>> folium.Marker([40.014984, -105.270546]).add_to(m)
>>> m
In [5]:
m = folium.Map(location = [40.1, -105.4], tiles = 'CartoDB Positron', zoom_start=10)
folium.Marker([40.014984, -105.270547]).add_to(m)
m
Out[5]:
Make this Notebook Trusted to load map: File -> Trust Notebook
There are multiple methods for adding and styling simple points on maps:¶
Try:
>>> folium.Marker([40.014984, -105.270546], icon=folium.Icon(color='red')).add_to(m)
Or:
>>> folium.vector_layers.CircleMarker(
location = [40.014984, -105.270546],
radius=10 ,
weight=3,
color='purple',
fill_color='red',
fill_opacity=1).add_to(m)
In [6]:
m = folium.Map(location = [40.1, -105.4], tiles = 'CartoDB Positron', zoom_start=10)
folium.vector_layers.CircleMarker(location = [40.014984, -105.270546], radius=10, weight=3, color='purple', fill_color='red', fill_opacity=1).add_to(m)
m
Out[6]:
Make this Notebook Trusted to load map: File -> Trust Notebook
In [7]:
m = folium.Map(location = [40.1, -105.4], tiles = 'CartoDB Positron', zoom_start=10)
folium.GeoJson('Boulder_Co_Tracts.geojson').add_to(m)
m
Out[7]:
Make this Notebook Trusted to load map: File -> Trust Notebook
Next, use Pandas to import the Boulder County Median Household Income csv file:¶
>>> MHHI = pd.read_csv('Boulder_Co_MHHI.csv', dtype={'GEOID10':str})
>>> MHHI
In [8]:
MHHI = pd.read_csv('Boulder_Co_MHHI.csv', dtype={'GEOID':str})
MHHI
Out[8]:
GEOID10 | Tract | State | State_FIPS | Count_FIPS | Tract_FIPS | FIPS | Area_Land | Area_Water | MHHI2014 | |
---|---|---|---|---|---|---|---|---|---|---|
0 | 8013012101 | Census Tract 121.01, Boulder County, Colorado | co | 8 | 13 | 12101 | 14000US08013012101 | 2859895 | 0 | 101328 |
1 | 8013012102 | Census Tract 121.02, Boulder County, Colorado | co | 8 | 13 | 12102 | 14000US08013012102 | 2882035 | 0 | 63333 |
2 | 8013012103 | Census Tract 121.03, Boulder County, Colorado | co | 8 | 13 | 12103 | 14000US08013012103 | 2305549 | 2740 | 87708 |
3 | 8013012104 | Census Tract 121.04, Boulder County, Colorado | co | 8 | 13 | 12104 | 14000US08013012104 | 2700890 | 96592 | 87875 |
4 | 8013012105 | Census Tract 121.05, Boulder County, Colorado | co | 8 | 13 | 12105 | 14000US08013012105 | 2475536 | 470 | 66885 |
... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... |
63 | 8013060700 | Census Tract 607, Boulder County, Colorado | co | 8 | 13 | 60700 | 14000US08013060700 | 10020054 | 82697 | 107273 |
64 | 8013060800 | Census Tract 608, Boulder County, Colorado | co | 8 | 13 | 60800 | 14000US08013060800 | 21250339 | 150276 | 44246 |
65 | 8013060900 | Census Tract 609, Boulder County, Colorado | co | 8 | 13 | 60900 | 14000US08013060900 | 7699944 | 28819 | 74954 |
66 | 8013061300 | Census Tract 613, Boulder County, Colorado | co | 8 | 13 | 61300 | 14000US08013061300 | 2106503 | 6895 | 151743 |
67 | 8013061400 | Census Tract 614, Boulder County, Colorado | co | 8 | 13 | 61400 | 14000US08013061400 | 2553846 | 8890 | 135644 |
68 rows × 10 columns
Now, we will use folium.Choropleth to join the Median Household Income tracts dataframe to the Boulder County Census Tracts geojson layer on the fly:¶
>>> m = folium.Map(location = [40.1, -105.4], tiles = 'CartoDB Positron', zoom_start = 10)
>>> folium.Choropleth(geo_data = 'Boulder_Co_Tracts.geojson',
data = MHHI,
columns = ['GEOID10', 'MHHI2014'],
key_on = 'feature.properties.GEOID10').add_to(m)
>>> m
In [9]:
m = folium.Map(location = [40.1, -105.4], tiles = 'CartoDB Positron', zoom_start = 10)
folium.Choropleth(geo_data = 'Boulder_Co_Tracts.geojson', data=MHHI, columns = ['GEOID10', 'MHHI2014'], key_on = 'feature.properties.GEOID10').add_to(m)
m
Out[9]:
Make this Notebook Trusted to load map: File -> Trust Notebook
Next, we'll modify the color palette¶
>>> m = folium.Map(location = [40.1, -105.4], tiles = 'Stamen Terrain', zoom_start = 10)
>>> folium.Choropleth(geo_data = 'Boulder_Co_Tracts.geojson',
data = MHHI,
columns = ['GEOID10', 'MHHI2014'],
key_on = 'feature.properties.GEOID10',
fill_color = 'RdYlGn').add_to(m)
>>> m
Note: fill_color accepts Color Brewer palettes
In [10]:
m = folium.Map(location = [40.1, -105.4], tiles = 'CartoDB Positron', zoom_start = 10)
folium.Choropleth(geo_data = 'Boulder_Co_Tracts.geojson',
data = MHHI,
columns = ['GEOID10', 'MHHI2014'],
key_on = 'feature.properties.GEOID10',
fill_color = 'RdYlGn').add_to(m).add_to(m)
m
Out[10]:
Make this Notebook Trusted to load map: File -> Trust Notebook
Export your map:¶
>>> m.save('my_map.html')
In [ ]:
m.save('my_map.html')
Advanced Choropleth¶
Now we will make a choropleth map of 2020 presidential election results in Colorado.¶
Start by importing the Colorado_Vote.geojson layer using GeoPandas:
>>> CO_Vote = gpd.read_file('Colorado_Vote.geojson', driver='GeoJSON')
Note: This data is from the New York Times.
In [11]:
CO_Vote = gpd.read_file('Colorado_Vote.geojson', driver='GeoJSON')
View some details about the CO_Vote geodataframe:¶
>>> CO_Vote
Note: In this data, pct_dem_lead represents an index the victory percentage of either party. Negative values represent the percentage by which Republicans won and positive values represent the percent by which Democrats won.
In [12]:
CO_Vote
Out[12]:
GEOID | votes_dem | votes_rep | votes_total | votes_per_sqkm | pct_dem_lead | geometry | |
---|---|---|---|---|---|---|---|
0 | 08001-187 | 430.0 | 464.0 | 920.0 | 1146.5 | -3.7 | POLYGON ((-104.79932 39.98680, -104.79683 39.9... |
1 | 08041-744 | 667.0 | 446.0 | 1140.0 | 772.9 | 19.4 | POLYGON ((-104.88658 38.85703, -104.88666 38.8... |
2 | 08041-745 | 116.0 | 137.0 | 261.0 | 23.8 | -8.0 | POLYGON ((-104.89584 38.83894, -104.88676 38.8... |
3 | 08059-060 | 252.0 | 294.0 | 560.0 | 1.1 | -7.5 | POLYGON ((-105.17096 39.40783, -105.17074 39.4... |
4 | 08059-061 | 703.0 | 504.0 | 1243.0 | 39.8 | 16.0 | POLYGON ((-105.39899 39.57012, -105.39904 39.5... |
... | ... | ... | ... | ... | ... | ... | ... |
3196 | 08001-188 | 305.0 | 422.0 | 740.0 | 1164.1 | -15.8 | POLYGON ((-104.79912 39.97759, -104.79966 39.9... |
3197 | 08041-740 | 863.0 | 938.0 | 1848.0 | 9.1 | -4.1 | POLYGON ((-104.86897 38.76925, -104.87056 38.7... |
3198 | 08001-189 | 290.0 | 421.0 | 731.0 | 1540.8 | -17.9 | POLYGON ((-104.80752 39.97593, -104.80703 39.9... |
3199 | 08041-741 | 193.0 | 292.0 | 493.0 | 10.2 | -20.1 | POLYGON ((-104.93542 38.92851, -104.93494 38.9... |
3200 | 08001-186 | 512.0 | 612.0 | 1153.0 | 1130.8 | -8.7 | POLYGON ((-104.78230 39.98638, -104.78250 39.9... |
3201 rows × 7 columns
Initialize a map including this GeoJson layer:¶
>>> m = folium.Map(location = [39, -105.7], tiles = 'CartoDB Positron', zoom_start=7)
>>> folium.GeoJson(CO_Vote).add_to(m)
>>> m
In [13]:
m = folium.Map(location = [39, -105.7], tiles = 'CartoDB Positron', zoom_start=7)
folium.GeoJson(CO_Vote).add_to(m)
m
Out[13]:
Make this Notebook Trusted to load map: File -> Trust Notebook