folium Documentation

repository·main·Indexed 27 days ago

https://github.com/python-visualization/folium

A Python library for creating interactive, Leaflet.js-based maps. It integrates with Python's data manipulation ecosystem to provide advanced mapping features, including Choropleth maps with Jenks Natural Breaks Optimization, custom GeoJson styling, and discrete or continuous colormaps via branca. The library supports custom layer ordering with CustomPane, custom tile sources (including images and patterns), and the integration of custom JavaScript and CSS resources. It also provides guidance on integrating maps into Flask applications and overlaying geodetic images using mercator_project or Cartopy warping.

Tokens
56.9K
Snippets
153
Records
233
Agent score
93%

What's inside folium

  1. Overview of Folium

    main

    Folium is a library for visualizing Python data on interactive Leaflet.js maps. It bridges the Python data ecosystem with the mapping capabilities of Leaflet.js.

    Key capabilities include:

    • Binding data to maps for choropleth visualizations.
    • Passing rich vector, raster, or HTML visualizations as markers.
    • Using built-in tilesets (e.g., OpenStreetMap, Mapbox) or custom tilesets.
    • Supporting Image, Video, GeoJSON, and TopoJSON overlays.
    • Providing various built-in vector layers.
  2. Explore Folium Plugins

    main

    Folium provides a wide range of plugins to extend map functionality, including animations, specialized markers, advanced controls, and data visualizations.

    Key categories of plugins include:

    • Animations & Visuals: Ant Path (flux animation), Boat Marker (yachts/sailboats), Pattern (pattern fills), Polyline Textpath (text along lines), and Terminator (day/night overlays).
    • Markers & Clustering: Beautify Icon (CSS-styled markers), Marker Cluster (high-performance clustering), Overlapping Marker Spiderfier (managing overlapping markers), and Semi Circle.
    • Drawing & Editing: Draw (user interface for drawing shapes), Geoman (interactive editing interface), and encoded formats like Polygon Encoded and Polyline Encoded.
    • Controls & UI: Fullscreen, Geocoder (geocoding/reverse geocoding), Locate Control, Measure Control, Mini Map, Mouse Position, Scroll Zoom Toggler, Search, and TreeLayerControl.
    • Time & Data Visualization: Heatmap, Heatmap with Time, Timeline, Timeslider Choropleth, Timestamped GeoJSON, and WMS Time Dimension.
    • Advanced Map Views: Dual Map (synchronized views), Side by Side Layers (split screen comparison), WebGL Earth (3D interactive globe), and Vector Tiles (gridded vector data).
  3. Use Timeline and TimelineSlider to show geospatial data over time

    main

    The Timeline plugin allows you to visualize changing geospatial data by using GeoJSON features that contain start and end time properties. To control the playback of these timelines, use the TimelineSlider plugin.

    Key differences from other plugins:

    • vs TimestampedGeoJson: Timeline expects each Feature to have its own start and end time in its properties. TimestampedGeoJson uses an array of start times and a global duration instead of individual end times.
    • vs Realtime: Timeline is designed for historical data (past events), whereas Realtime is used for live updates.
    import folium
    from folium.utilities import JsCode
    from folium.features import GeoJsonPopup
    from folium.plugins.timeline import Timeline, TimelineSlider
    import requests
    
    m = folium.Map()
    
    data = requests.get(
        "https://raw.githubusercontent.com/python-visualization/folium-example-data/main/historical_country_borders.json"
    ).json()
    
    timeline = Timeline(
        data,
        style=JsCode("""
            function (data) {
                function getColorFor(str) {
                    var hash = 0;
                    for (var i = 0; i < str.length; i++) {
                        hash = str.charCodeAt(i) + ((hash << 5) - hash);
                    }
                    var red = (hash >> 24) & 0xff;
                    var grn = (hash >> 16) & 0xff;
                    var blu = (hash >> 8) & 0xff;
                    return "rgb(" + red + "," + grn + "," + blu + ")";
                }
                return {
                    stroke: false,
                    color: getColorFor(data.properties.name),
                    fillOpacity: 0.5,
                };
            }
        """)
    ).add_to(m)
    
    GeoJsonPopup(fields=['name'], labels=True).add_to(timeline)
    
    TimelineSlider(
        auto_play=False,
        show_ticks=True,
        enable_keyboard_controls=True,
        playback_duration=30000,
    ).add_timelines(timeline).add_to(m)
  4. Embed IFrame in popups

    main

    To embed complex HTML or even other Folium elements (like a nested Map) inside a popup, use branca.element.IFrame. This prevents the popup content from interfering with the main map's layout.

    Steps:

    1. Create your HTML content.
    2. Wrap the HTML in a branca.element.IFrame(html=html, width=W, height=H).
    3. Pass the IFrame object to folium.Popup(iframe, max_width=W).
    4. Add the popup to your map feature.
    import folium
    import branca
    
    m = folium.Map([43, -100], zoom_start=4)
    
    html = """<h1 style='color: blue;'> This popup is an Iframe</h1>"""
    
    iframe = branca.element.IFrame(html=html, width=500, height=300)
    popup = folium.Popup(iframe, max_width=500)
    
    folium.Marker([30, -100], popup=popup).add_to(m)
  5. Add a search box to a map using Geocoder plugin

    main

    You can add a search box to a folium.Map instance to allow users to search for geographic features (cities, countries, addresses, etc.) directly on the map. This plugin uses the Nominatim service from OpenStreetMap.

    Note: Please respect the Nominatim usage policy: https://operations.osmfoundation.org/policies/nominatim/

    import folium
    import folium.plugins
    
    m = folium.Map()
    folium.plugins.Geocoder().add_to(m)
    m
  6. Disable tile wrapping with no_wrap

    main

    To prevent tiles from wrapping around the world, pass a folium.TileLayer with the no_wrap=True argument to the tiles parameter of folium.Map. This ensures the map domain is not wrapped.

    import folium
    
    m = folium.Map(
        tiles=folium.TileLayer(no_wrap=True)
    )
    folium.Marker(location=[0, 0], popup="The map domain here is not wrapped.").add_to(m)
    m
  7. Use SideBySideLayers to compare two map layers

    main

    The SideBySideLayers plugin allows you to compare two different map layers using a vertical separator that the user can drag.

    To use it:

    1. Instantiate folium.plugins.SideBySideLayers with layer_left and layer_right arguments.
    2. Add both the left and right layers to your map.
    3. Add the SideBySideLayers instance to your map.

    Note: If you are using a LayerControl on your map and want the layers used for the side-by-side comparison to remain visible/enabled, you should initialize the layers with control=False.

    import folium
    import folium.plugins
    
    m = folium.Map(location=(30, 20), zoom_start=4)
    
    layer_right = folium.TileLayer('openstreetmap')
    layer_left = folium.TileLayer('cartodbpositron')
    
    sbs = folium.plugins.SideBySideLayers(layer_left=layer_left, layer_right=layer_right)
    
    layer_left.add_to(m)
    layer_right.add_to(m)
    sbs.add_to(m)
    
    m
  8. Create an ImageOverlay from a numpy array

    main

    You can generate dynamic maps by passing a numpy array to ImageOverlay.

    Requirements

    • numpy must be installed.
    • You must provide a colormap argument.

    Colormap Format

    The colormap must be a function (e.g., a lambda) that accepts a value x and returns an RGBA tuple: lambda x: (R, G, B, A), where R, G, B, A are floats between 0 and 1.

    Handling Orientation and Projection

    • origin='lower': Use this to inform Folium that the first lines of the array should be plotted at the bottom of the image (matching numpy.imshow behavior).
    • mercator_project=True: Because Leaflet uses Mercator projection, raw numpy arrays may not align correctly with geographic coordinates (like Polylines). Setting mercator_project=True allows Folium to handle the projection math so the array aligns with the map's coordinate system.
    import numpy as np
    import folium
    
    # Create a dummy numpy array
    image = np.zeros((61, 1))
    image[45, :] = 1.0
    
    m = folium.Map([37, 0], zoom_start=3)
    
    # Add a polyline to verify alignment
    folium.PolyLine([[45, -60], [45, 60]]).add_to(m)
    
    # Use ImageOverlay with mercator_project=True for correct alignment
    folium.raster_layers.ImageOverlay(
        image=image,
        bounds=[[0, -60], [60, 60]],
        origin="lower",
        colormap=lambda x: (1, 0, 0, x),
        mercator_project=True,
    ).add_to(m)
  9. Show live-updating data on WebGLEarth with WebGLEarthRealtime

    main

    Use WebGLEarthRealtime to fetch and display live data on the 3D globe. It requires a source_url for the data and an interval (in milliseconds). The on_update parameter accepts a folium.JsCode object containing a JavaScript function that defines how the data should be rendered on the globe (e.g., updating marker positions).

    import folium
    from folium import JsCode
    from folium.plugins import WebGLEarth, WebGLEarthRealtime
    
    m = folium.Map()
    
    globe = WebGLEarth(center=[0, 0], zoom=1.8)
    globe.add_to(m)
    
    WebGLEarthRealtime(
        source_url="https://api.wheretheiss.at/v1/satellites/25544",
        interval=3000,
        on_update=JsCode("""
            function(data, earth) {
                if (window._issMarker) window._issMarker.removeFrom(earth);
                window._issMarker = WE.marker(
                    [data.latitude, data.longitude]
                ).addTo(earth);
                window._issMarker.bindPopup(
                    '<b>ISS</b><br>'
                    + 'Lat: ' + data.latitude.toFixed(2)
                    + '<br>Lng: ' + data.longitude.toFixed(2)
                    + '<br>Alt: ' + data.altitude.toFixed(1) + ' km'
                );
            }
        """),
    ).add_to(globe)
    
    m
  10. Add custom tile layers to WebGLEarth

    main

    You can overlay additional tile layers on top of the default OpenStreetMap tiles in the 3D globe using WebGLEarthTileLayer. This allows for custom map styling or additional data overlays.

    import folium
    from folium.plugins import WebGLEarth, WebGLEarthTileLayer
    
    m = folium.Map()
    
    globe = WebGLEarth(center=[20, 0], zoom=2)
    globe.add_to(m)
    
    WebGLEarthTileLayer(
        url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png",
        attribution="© OpenStreetMap contributors",
        opacity=0.5,
    ).add_to(globe)
    
    m
  11. Use the DualMap plugin to create synchronized side-by-side maps

    main

    The folium.plugins.DualMap class creates two maps side-by-side that synchronize panning and zooming. It accepts the same arguments as the standard folium.Map class, with the exception of 'width', 'height', 'left', 'top', and 'position'.

    You can access the two individual submaps using the m1 and m2 attributes to add specific layers, tile sets, or markers to one map without affecting the other.

    import folium
    import folium.plugins
    
    # Basic DualMap initialization
    m = folium.plugins.DualMap(location=(52.1, 5.1), zoom_start=8)
    
    # Accessing submaps to add different tile layers
    m = folium.plugins.DualMap(location=(52.1, 5.1), tiles=None, zoom_start=8)
    folium.TileLayer("openstreetmap").add_to(m.m1)
    folium.TileLayer("cartodbpositron").add_to(m.m2)