Online Folium Compiler

Make web maps in your browser, with markers and popups, lines and circles, GeoJSON layers, choropleths and heat maps.

Python
# Source:
# https://python-visualization.github.io/folium/latest/getting_started.html
import pandas
import requests
import folium

state_geo = requests.get(
    "https://raw.githubusercontent.com/python-visualization/folium-example-data/main/us_states.json"
).json()
state_data = pandas.read_csv(
    "https://raw.githubusercontent.com/python-visualization/folium-example-data/main/us_unemployment_oct_2012.csv"
)

map = folium.Map(location=[38, -112], zoom_start=3)

folium.Choropleth(
    geo_data=state_geo,
    name="choropleth",
    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 (%)",
).add_to(map)

folium.LayerControl().add_to(map)

map

Folium makes maps from Python. It writes the HTML and JavaScript for a Leaflet map, with OpenStreetMap tiles by default, and you add markers, lines, GeoJSON shapes and colored regions on top. People use it to plot store locations, show routes and map statistics by state or country. This page is an online Folium compiler: the code runs in your browser, so you can try it without installing anything. Run the example first, then paste any snippet below into a new cell to try it.

What the example does

requests.get(...).json() loads a GeoJSON file of US state outlines, and pandas.read_csv() loads each state's unemployment rate for October 2012. folium.Map(location=[38, -112], zoom_start=3) centers the map at latitude 38, longitude -112. folium.Choropleth colors each state by its rate. columns=["State", "Unemployment"] names the key and value columns in the table, and key_on="feature.id" names the GeoJSON field that holds the same key, here two-letter codes such as AL. fill_color="YlGn" is a palette from pale yellow to dark green, and legend_name labels the color scale. folium.LayerControl() adds a control that lists the base map and the "choropleth" layer. The last line, map, displays the result.

Add markers with popups

tooltip is text that shows when the pointer is over a marker, and popup fills the marker's popup box. folium.Icon sets the pin's color and symbol:

import folium

places = {
    "Eiffel Tower": [48.8584, 2.2945],
    "Louvre": [48.8606, 2.3376],
    "Notre-Dame": [48.8530, 2.3499],
}

m = folium.Map(location=[48.857, 2.32], zoom_start=13)
for name, location in places.items():
    folium.Marker(
        location,
        tooltip=name,
        popup=f"<b>{name}</b><br>{location[0]}, {location[1]}",
        icon=folium.Icon(color="red", icon="info-sign"),
    ).add_to(m)
m

Draw lines and circles

PolyLine connects points in order. Circle takes its radius in meters and CircleMarker in screen pixels. fit_bounds() zooms to fit a list of points, so the map needs no starting location:

import folium

# Big Ben, the London Eye and the Tower of London
route = [[51.5007, -0.1246], [51.5033, -0.1196], [51.5081, -0.0759]]

m = folium.Map()
folium.PolyLine(route, color="blue", weight=4).add_to(m)
folium.CircleMarker(route[0], radius=8, color="green", fill=True).add_to(m)
folium.Circle(route[-1], radius=300, color="red", fill=True).add_to(m)
m.fit_bounds(route)
m

Add GeoJSON with your own styles

folium.GeoJson draws a GeoJSON dict, file or GeoDataFrame. style_function gets each feature and returns its style, so the color can depend on a property. GeoJSON lists each position as longitude, latitude, the reverse of the latitude, longitude that folium takes:

import folium

def square(lon, lat, name, risk):
    ring = [[lon, lat], [lon + 0.04, lat], [lon + 0.04, lat + 0.02],
            [lon, lat + 0.02], [lon, lat]]
    return {"type": "Feature", "properties": {"name": name, "risk": risk},
            "geometry": {"type": "Polygon", "coordinates": [ring]}}

def style(feature):
    color = "red" if feature["properties"]["risk"] == "high" else "green"
    return {"fillColor": color, "color": "black", "weight": 1}

north = square(-0.14, 51.51, "North", "high")
south = square(-0.14, 51.49, "South", "low")
zones = {"type": "FeatureCollection", "features": [north, south]}

m = folium.Map(location=[51.51, -0.12], zoom_start=13)
folium.GeoJson(zones, style_function=style,
               tooltip=folium.GeoJsonTooltip(fields=["name", "risk"])).add_to(m)
m

To draw a GeoDataFrame, see the GeoPandas example.

Show where points cluster with a heat map

HeatMap takes a list or array of latitude, longitude rows, with an optional third column for weight:

import folium
import numpy as np
from folium.plugins import HeatMap

rng = np.random.default_rng(0)
points = np.vstack([
    rng.normal([40.758, -73.985], 0.005, size=(300, 2)),  # around Times Square
    rng.normal([40.706, -74.009], 0.004, size=(200, 2)),  # around Wall Street
])

m = folium.Map(location=[40.73, -73.99], zoom_start=12)
HeatMap(points, radius=15).add_to(m)
m

Good to know

  • The map is a web page. Python writes the HTML, and the browser then loads Leaflet and the map tiles from the internet, so a map needs a connection to show its background.
  • In a choropleth, regions with no matching row are filled black, the default nan_fill_color. If every region is black, key_on does not match the keys in your table.
  • m.save("map.html") writes the map as one HTML file you can open in any browser. Files your code saves appear in the sidebar's Data tab.