Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

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.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
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.

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.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
import 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.

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.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

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.