Using GeoJson — Folium 0.19.0 documentation (2025)

Loading data#

Let us load a GeoJSON file representing the US states.

[2]:
import requestsgeo_json_data = requests.get( "https://raw.githubusercontent.com/python-visualization/folium-example-data/main/us_states.json").json()

It is a classical GeoJSON FeatureCollection (see https://en.wikipedia.org/wiki/GeoJSON) of the form :

{ "type": "FeatureCollection", "features": [ { "properties": {"name": "Alabama"}, "id": "AL", "type": "Feature", "geometry": { "type": "Polygon", "coordinates": [[[-87.359296, 35.00118], ...]] } }, { "properties": {"name": "Alaska"}, "id": "AK", "type": "Feature", "geometry": { "type": "MultiPolygon", "coordinates": [[[[-131.602021, 55.117982], ... ]]] } }, ... ] }

A first way of drawing it on a map, is simply to use folium.GeoJson :

[3]:
m = folium.Map([43, -100], zoom_start=4)folium.GeoJson(geo_json_data).add_to(m)m
[3]:

Make this Notebook Trusted to load map: File -> Trust Notebook

Note that you can avoid loading the file on yourself, by providing a (local) file path or a url.

[4]:
m = folium.Map([43, -100], zoom_start=4)url = "https://raw.githubusercontent.com/python-visualization/folium-example-data/main/us_states.json"folium.GeoJson(url).add_to(m)m
[4]:

Make this Notebook Trusted to load map: File -> Trust Notebook

You can pass a geopandas object.

[5]:
import geopandasgdf = geopandas.read_file(url)m = folium.Map([43, -100], zoom_start=4)folium.GeoJson( gdf,).add_to(m)m
[5]:

Make this Notebook Trusted to load map: File -> Trust Notebook

Click on zoom#

You can enable an option that if you click on a part of the geometry the map will zoom in to that.

Try it on the map below:

[6]:
m = folium.Map([43, -100], zoom_start=4)folium.GeoJson(geo_json_data, zoom_on_click=True).add_to(m)m
[6]:

Make this Notebook Trusted to load map: File -> Trust Notebook

Styling#

Now this is cool and simple, but we may be willing to choose the style of the data.

You can provide a function of the form lambda feature: {} that sets the style of each feature.

For possible options, see:

[7]:
m = folium.Map([43, -100], zoom_start=4)folium.GeoJson( geo_json_data, style_function=lambda feature: { "fillColor": "#ffff00", "color": "black", "weight": 2, "dashArray": "5, 5", },).add_to(m)m
[7]:

Make this Notebook Trusted to load map: File -> Trust Notebook

What’s cool in providing a function, is that you can specify a style depending on the feature. For example, if you want to visualize in green all states whose name contains the letter ‘E’, just do:

[8]:
m = folium.Map([43, -100], zoom_start=4)folium.GeoJson( geo_json_data, style_function=lambda feature: { "fillColor": "green" if "e" in feature["properties"]["name"].lower() else "#ffff00", "color": "black", "weight": 2, "dashArray": "5, 5", },).add_to(m)m
[8]:

Make this Notebook Trusted to load map: File -> Trust Notebook

Wow, this looks almost like a choropleth. To do one, we just need to compute a color for each state.

Let’s imagine we want to draw a choropleth of unemployment in the US.

First, we may load the data:

[9]:
import pandasunemployment = pandas.read_csv( "https://raw.githubusercontent.com/python-visualization/folium-example-data/main/us_unemployment_oct_2012.csv")unemployment.head(5)
[9]:
State Unemployment
0 AL 7.1
1 AK 6.8
2 AZ 8.1
3 AR 7.2
4 CA 10.1

Now we need to create a function that maps one value to a RGB color (of the form #RRGGBB). For this, we’ll use colormap tools from folium.colormap.

[10]:
from branca.colormap import linearcolormap = linear.YlGn_09.scale( unemployment.Unemployment.min(), unemployment.Unemployment.max())print(colormap(5.0))colormap
#d8f0a3ff
[10]:

We need also to convert the table into a dictionary, in order to map a feature to it’s unemployment value.

[11]:
unemployment_dict = unemployment.set_index("State")["Unemployment"]unemployment_dict["AL"]
[11]:
np.float64(7.1)

Now we can do the choropleth.

[12]:
m = folium.Map([43, -100], zoom_start=4)folium.GeoJson( geo_json_data, name="unemployment", style_function=lambda feature: { "fillColor": colormap(unemployment_dict[feature["id"]]), "color": "black", "weight": 1, "dashArray": "5, 5", "fillOpacity": 0.9, },).add_to(m)folium.LayerControl().add_to(m)m
[12]:

Make this Notebook Trusted to load map: File -> Trust Notebook

Of course, if you can create and/or use a dictionary providing directly the good color. Thus, the finishing seems faster:

[13]:
color_dict = {key: colormap(unemployment_dict[key]) for key in unemployment_dict.keys()}
[14]:
m = folium.Map([43, -100], zoom_start=4)folium.GeoJson( geo_json_data, style_function=lambda feature: { "fillColor": color_dict[feature["id"]], "color": "black", "weight": 1, "dashArray": "5, 5", "fillOpacity": 0.9, },).add_to(m)
[14]:
<folium.features.GeoJson at 0x7f0b2053fb00>

Note that adding a color legend may be a good idea.

[15]:
colormap.caption = "Unemployment color scale"colormap.add_to(m)m
[15]:

Make this Notebook Trusted to load map: File -> Trust Notebook

Caveat

When using style_function in a loop you may encounter Python’s ‘Late Binding Closure’ gotcha! See https://docs.python-guide.org/writing/gotchas/#late-binding-closures for more info. There are a few ways around it from using a GeoPandas object instead, to “hacking” your style_function to force early closure, like:

for geom, my_style in zip(geoms, my_styles): style = my_style style_function = lambda x, style=style: style folium.GeoJson( data=geom, style_function=style_function, ).add_to(m)

Highlight function#

The GeoJson class provides a highlight_function argument, which works similarly to style_function, but applies on mouse events. In the following example the fill color will change when you hover your mouse over a feature.

[16]:
m = folium.Map([43, -100], zoom_start=4)folium.GeoJson( geo_json_data, highlight_function=lambda feature: { "fillColor": ( "green" if "e" in feature["properties"]["name"].lower() else "#ffff00" ), },).add_to(m)m
[16]:

Make this Notebook Trusted to load map: File -> Trust Notebook

Keep highlighted while popup is open#

The GeoJson class provides a popup_keep_highlighted boolean argument. Whenever a GeoJson layer is associated with a popup and a highlight function is defined, this argument allows you to decide if the highlighting should remain active while the popup is open.

[17]:
m = folium.Map([43, -100], zoom_start=4)popup = folium.GeoJsonPopup(fields=["name"])folium.GeoJson( geo_json_data, highlight_function=lambda feature: { "fillColor": ( "green" if "e" in feature["properties"]["name"].lower() else "#ffff00" ), }, popup=popup, popup_keep_highlighted=True,).add_to(m)m
[17]:

Make this Notebook Trusted to load map: File -> Trust Notebook

Using GeoJson — Folium 0.19.0 documentation (2025)
Top Articles
Latest Posts
Recommended Articles
Article information

Author: Gov. Deandrea McKenzie

Last Updated:

Views: 5997

Rating: 4.6 / 5 (66 voted)

Reviews: 81% of readers found this page helpful

Author information

Name: Gov. Deandrea McKenzie

Birthday: 2001-01-17

Address: Suite 769 2454 Marsha Coves, Debbieton, MS 95002

Phone: +813077629322

Job: Real-Estate Executive

Hobby: Archery, Metal detecting, Kitesurfing, Genealogy, Kitesurfing, Calligraphy, Roller skating

Introduction: My name is Gov. Deandrea McKenzie, I am a spotless, clean, glamorous, sparkling, adventurous, nice, brainy person who loves writing and wants to share my knowledge and understanding with you.