import os
import folium
print(folium.__version__)
0.3.0.dev
m = folium.Map(location=[45.5236, -122.6750])
To display it in a Jupyter notebook, simply ask for the object representation:
m
To save it in a file:
m.save(os.path.join('results', 'Quickstart_0.html'))
Folium defaults to OpenStreetMap tiles, but Stamen Terrain, Stamen Toner, Mapbox Bright, and Mapbox Control room tiles are built in:
folium.Map(
location=[45.5236, -122.6750],
tiles='Stamen Toner',
zoom_start=13
)
Folium also supports Cloudmade and Mapbox custom tilesets- simply pass your key to the API_key keyword:
folium.Map(location=[45.5236, -122.6750],
tiles='Mapbox',
API_key='your.API.key')
Lastly, Folium supports passing any Leaflet.js compatible custom tileset:
folium.Map(location=[45.372, -121.6972],
zoom_start=12,
tiles='http://{s}.tiles.yourtiles.com/{z}/{x}/{y}.png',
attr='My Data Attribution')
Folium supports the plotting of numerous marker types, starting with a simple Leaflet style location marker with popup text:
m = folium.Map(
location=[45.372, -121.6972],
zoom_start=12,
tiles='Stamen Terrain'
)
folium.Marker([45.3288, -121.6625], popup='Mt. Hood Meadows').add_to(m)
folium.Marker([45.3311, -121.7113], popup='Timberline Lodge').add_to(m)
m.save(os.path.join('results', 'Quickstart_1.html'))
m
Folium supports colors and marker icon types (from bootstrap)
m = folium.Map(
location=[45.372, -121.6972],
zoom_start=12,
tiles='Stamen Terrain'
)
folium.Marker(
location=[45.3288, -121.6625],
popup='Mt. Hood Meadows',
icon=folium.Icon(icon='cloud')
).add_to(m)
folium.Marker(
location=[45.3311, -121.7113],
popup='Timberline Lodge',
icon=folium.Icon(color='green')
).add_to(m)
folium.Marker(
location=[45.3300, -121.6823],
popup='Some Other Location',
icon=folium.Icon(color='red', icon='info-sign')
).add_to(m)
m.save(os.path.join('results', 'Quickstart_2.html'))
m
Folium also supports circle-style markers, with custom size and color:
m = folium.Map(
location=[45.5236, -122.6750],
tiles='Stamen Toner',
zoom_start=13
)
folium.Marker(
location=[45.5244, -122.6699],
popup='The Waterfront'
).add_to(m)
folium.CircleMarker(
location=[45.5215, -122.6261],
radius=50,
popup='Laurelhurst Park',
color='#3186cc',
fill_color='#3186cc'
).add_to(m)
m.save(os.path.join('results', 'Quickstart_3.html'))
m
Folium has a convenience function to enable lat/lng popovers:
m = folium.Map(
location=[46.1991, -122.1889],
tiles='Stamen Terrain',
zoom_start=13
)
m.add_child(folium.LatLngPopup())
m.save(os.path.join('results', 'Quickstart_4.html'))
m
Click-for-marker functionality will allow for on-the-fly placement of markers:
m = folium.Map(
location=[46.8527, -121.7649],
tiles='Stamen Terrain',
zoom_start=13
)
folium.Marker(
[46.8354, -121.7325],
popup='Camp Muir'
).add_to(m)
m.add_child(folium.ClickForMarker(popup='Waypoint'))
m.save(os.path.join('results', 'Quickstart_5.html'))
m
Folium also supports the Polygon marker set from the Leaflet-DVF:
m = folium.Map(
location=[45.5236, -122.6750],
zoom_start=13
)
folium.RegularPolygonMarker(
location=[45.5012, -122.6655],
popup='Ross Island Bridge',
fill_color='#132b5e',
number_of_sides=3,
radius=10
).add_to(m)
folium.RegularPolygonMarker(
location=[45.5132, -122.6708],
popup='Hawthorne Bridge',
fill_color='#45647d',
number_of_sides=4,
radius=10
).add_to(m)
folium.RegularPolygonMarker(
location=[45.5275, -122.6692],
popup='Steel Bridge',
fill_color='#769d96',
number_of_sides=6,
radius=10
).add_to(m)
folium.RegularPolygonMarker(
location=[45.5318, -122.6745],
popup='Broadway Bridge',
fill_color='#769d96',
number_of_sides=8,
radius=10
).add_to(m)
m.save(os.path.join('results', 'Quickstart_6.html'))
m
vis1 = os.path.join('data', 'vis1.json')
vis2 = os.path.join('data', 'vis2.json')
vis3 = os.path.join('data', 'vis3.json')
import json
m = folium.Map(
location=[46.3014, -123.7390],
zoom_start=7,
tiles='Stamen Terrain'
)
folium.RegularPolygonMarker(
location=[47.3489, -124.708],
fill_color='#43d9de',
radius=12,
popup=folium.Popup(max_width=450).add_child(
folium.Vega(json.load(open(vis1)), width=450, height=250))
).add_to(m)
folium.RegularPolygonMarker(
location=[44.639, -124.5339],
fill_color='#43d9de',
radius=12,
popup=folium.Popup(max_width=450).add_child(
folium.Vega(json.load(open(vis2)), width=450, height=250))
).add_to(m)
folium.RegularPolygonMarker(
location=[46.216, -124.1280],
fill_color='#43d9de',
radius=12,
popup=folium.Popup(max_width=450).add_child(
folium.Vega(json.load(open(vis3)), width=450, height=250))
).add_to(m)
m.save(os.path.join('results', 'Quickstart_7.html'))
m
For more information about popups, please visit Popups.ipynb
Both GeoJSON and TopoJSON layers can be passed to the map as an overlay, and multiple layers can be visualized on the same map:
antarctic_ice_edge = os.path.join('data', 'antarctic_ice_edge.json')
antarctic_ice_shelf_topo = os.path.join('data', 'antarctic_ice_shelf_topo.json')
m = folium.Map(
location=[-59.1759, -11.6016],
tiles='Mapbox Bright',
zoom_start=2
)
folium.GeoJson(
open(antarctic_ice_edge),
name='geojson'
).add_to(m)
folium.TopoJson(
open(antarctic_ice_shelf_topo),
'objects.antarctic_ice_shelf',
name='topojson'
).add_to(m)
folium.LayerControl().add_to(m)
m.save(os.path.join('results', 'Quickstart_8.html'))
m
Folium allows for the binding of data between Pandas DataFrames/Series and Geo/TopoJSON geometries. Color Brewer sequential color schemes are built-in to the library, and can be passed to quickly visualize different combinations:
import pandas as pd
state_geo = os.path.join('data', 'us-states.json')
state_unemployment = os.path.join('data', 'US_Unemployment_Oct2012.csv')
state_data = pd.read_csv(state_unemployment)
# Let Folium determine the scale.
m = folium.Map(location=[48, -102], zoom_start=3)
m.choropleth(
geo_path=state_geo,
data=state_data,
columns=['State', 'Unemployment'],
key_on='feature.id',
fill_color='YlGn',
fill_opacity=0.7,
line_opacity=0.2,
legend_name='Unemployment Rate (%)'
)
m.save(os.path.join('results', 'Quickstart_9.html'))
m
Folium creates the legend on the upper right based on a D3 threshold scale, and makes the best-guess at values via quantiles. Passing your own threshold values is simple:
# Control the scale.
from branca.utilities import split_six
threshold_scale = split_six(state_data['Unemployment'])
m = folium.Map(location=[48, -102], zoom_start=3)
m.choropleth(
geo_path=state_geo,
data=state_data,
columns=['State', 'Unemployment'],
key_on='feature.id',
fill_color='BuPu',
fill_opacity=0.7,
line_opacity=0.5,
legend_name='Unemployment Rate (%)',
threshold_scale=threshold_scale,
reset=True
)
m.save(os.path.join('results', 'Quickstart_10.html'))
m
By binding data via the Pandas DataFrame, different datasets can be quickly visualized. In the following example, the df DataFrame contains six columns with different economic data, a few of which we will visualize:
unemployment = pd.read_csv(state_unemployment)
m = folium.Map([43, -100], zoom_start=4)
m.choropleth(
geo_str=open(state_geo).read(),
data=unemployment,
columns=['State', 'Unemployment'],
key_on='feature.id',
fill_color='YlGn',
threshold_scale=[3.0, 7.0, 8.0, 9.0, 9.0]
)
m.save(os.path.join('results', 'Quickstart_11.html'))
m
import branca
county_data = os.path.join('data', 'us_county_data.csv')
county_geo = os.path.join('data', 'us_counties_20m_topo.json')
df = pd.read_csv(county_data, na_values=[' '])
colorscale = branca.colormap.linear.YlOrRd.scale(0, 50e3)
employed_series = df.set_index('FIPS_Code')['Employed_2011']
def style_function(feature):
employed = employed_series.get(int(feature['id'][-5:]), None)
return {
'fillOpacity': 0.5,
'weight': 0,
'fillColor': '#black' if employed is None else colorscale(employed)
}
m = folium.Map(
location=[48, -102],
tiles='cartodbpositron',
zoom_start=3
)
folium.TopoJson(
open(county_geo),
'objects.us_counties_20m',
style_function=style_function
).add_to(m)
m.save(os.path.join('results', 'Quickstart_12.html'))
m
colorscale = branca.colormap.linear.YlGnBu.scale(0, 30)
employed_series = df.set_index('FIPS_Code')['Unemployment_rate_2011']
def style_function(feature):
employed = employed_series.get(int(feature['id'][-5:]), None)
return {
'fillOpacity': 0.5,
'weight': 0,
'fillColor': '#black' if employed is None else colorscale(employed)
}
m = folium.Map(
location=[48, -102],
tiles='cartodbpositron',
zoom_start=3
)
folium.TopoJson(
open(county_geo),
'objects.us_counties_20m',
style_function=style_function
).add_to(m)
m.save(os.path.join('results', 'Quickstart_13.html'))
m
colorscale = branca.colormap.linear.PuRd.scale(0, 100000)
employed_series = df.set_index('FIPS_Code')['Median_Household_Income_2011'].dropna()
def style_function(feature):
employed = employed_series.get(int(feature['id'][-5:]), None)
return {
'fillOpacity': 0.5,
'weight': 0,
'fillColor': '#black' if employed is None else colorscale(employed)
}
m = folium.Map(
location=[48, -102],
tiles='cartodbpositron',
zoom_start=3)
folium.TopoJson(
open(county_geo),
'objects.us_counties_20m',
style_function=style_function
).add_to(m)
m.save(os.path.join('results', 'Quickstart_14.html'))
m