Folium turns geospatial data into interactive, browser-viewable maps from Python. Create a folium.Map as the container, add data as layers, and then add controls such as a layer switcher. For polygons, use GeoJSON; for dense point data, consider clustering; for changing polygon styles over time, use TimeSliderChoropleth.
Check your Folium version first
The official user guide currently labels its examples as Folium 1.0.0rc1, so check the version installed in your environment before relying on a particular API example. You can record it in Python with:
import folium
print(folium.__version__)
For reproducible work, record and pin the package versions used by your project, then check examples against the installed Folium version. The official user guide organizes the API around maps, layers, GeoJSON, choropleths, and plugins.
Create a map and add geospatial data
A Folium map is the base container. Give it a center coordinate and starting zoom, then add data layers to it. For example:
Free tools Windows power users keep installed
One-click scans. No signup required.
#1 Best Overall
import folium
m = folium.Map([43, -100], zoom_start=4)
Render vector data with folium.GeoJson. Its input can be a URL, a local file path, a parsed GeoJSON object, or a GeoPandas GeoDataFrame. For example, if geo_json_data contains supported GeoJSON data:
folium.GeoJson(
geo_json_data,
name="boundaries",
zoom_on_click=True,
).add_to(m)
folium.LayerControl().add_to(m)
m.save("map.html")
zoom_on_click=True makes the map zoom to a geometry when it is clicked. A layer name and LayerControl let readers toggle named layers. See the guide’s GeoJSON examples for supported inputs and rendering options.
Rank #2
Choose a display method for your geometry and interactions
| Data and purpose | Folium approach | Useful interaction or trade-off |
|---|---|---|
| Points that need individual details | folium.Marker |
Add popups or icons to markers. |
| Many points that would crowd a map | folium.plugins.MarkerCluster |
Groups markers; the official example supports popups, custom icons, a layer name, and a layer control. |
| Coordinate arrays where flexibility is less important | folium.plugins.FastMarkerCluster |
The official guide describes it as faster but less flexible than MarkerCluster. |
| Lines or polygons provided as GeoJSON | folium.GeoJson |
Can render vector geometries and support click-to-zoom. |
| Polygon values that vary by region | folium.GeoJson with a color scale |
Style each feature using its joined value. |
| Polygon styles that vary by timestamp | folium.plugins.TimeSliderChoropleth |
Uses timestamped colors and opacity keyed by feature ID. |
Folium’s documentation does not establish a universal maximum marker count or a browser-independent performance threshold. Test dense maps with the data and browser conditions that matter to your users rather than treating a particular marker count as a guaranteed limit. The official MarkerCluster guide demonstrates the clustered-marker options.
Build a choropleth with a reliable feature-ID join
A choropleth colors geographic areas according to tabular values. The critical step is matching each GeoJSON feature to the correct row in your data. The example below assumes values is a pandas object with State and Unemployment columns, and that each GeoJSON feature has an id matching a value in State.
Do these 3 things before closing this tab:
1Repair Windows errors before they cause bigger problems2Fix the driver behind crashes, sound loss and screen glitches3Clear out junk files and repair common Windows errorsimport folium
from branca.colormap import linear
m = folium.Map([43, -100], zoom_start=4)
colormap = linear.YlGn_09.scale(
values["Unemployment"].min(),
values["Unemployment"].max(),
)
value_by_id = values.set_index("State")["Unemployment"]
folium.GeoJson(
geo_json_data,
name="Unemployment",
style_function=lambda feature: {
"fillColor": colormap(value_by_id[feature["id"]]),
"color": "black",
"weight": 1,
"fillOpacity": 0.9,
},
).add_to(m)
folium.LayerControl().add_to(m)
m.save("choropleth.html")
This approach looks up a tabular value by feature ID, maps it through a Branca colormap, and applies the result as the feature fill color. The official choropleth guide shows this style of feature-based rendering.
Check joins and geographic data before styling
- Confirm that the feature IDs and table keys use the same values and types. A mismatch can leave features without the intended data or cause lookups to fail.
- Check for missing values and decide how areas without data should appear; do not let missing data silently masquerade as a measured value.
- Validate geometries if features fail to render or appear malformed.
- Confirm the coordinate reference system and coordinate order expected by the data being passed to Folium. Incorrect coordinates can put features in the wrong place.
Represent time-varying polygon data
Use TimeSliderChoropleth when polygon styling changes by timestamp. It takes serialized GeoJSON and a styledict keyed by feature ID. Each timestamp’s style can specify a color and opacity, and init_timestamp chooses the starting position on the slider. Because areas can be sampled at different times, the timestamps need not represent a uniform sampling interval.
Rank #4
The exact structure of the style dictionary matters: its outer keys identify features, and the styles for a feature are associated with timestamps. A conceptual structure is:
styledict = {
"feature_id": {
"timestamp": {"color": "#2c7fb8", "opacity": 0.8}
}
}
Replace the illustrative keys and style values with IDs present in your GeoJSON and the timestamps available in your data. Consult the TimeSliderChoropleth documentation for the plugin’s input format and examples.
Best Value
Save and inspect the result
Save the map to an HTML file with m.save("map.html"), then open it in a browser to check layer visibility, zoom, popups, and whether features render in the expected locations. For maps that appear incomplete or incorrect, inspect the input geometries, coordinate system, feature IDs, and missing table values before changing the styling code.

