Folium#

Download this notebook from GitHub (right-click to download).


Demonstrates the use of Folium in Panel.

import folium as fm
import pandas as pd
import param
import panel as pn
import random
pn.extension(sizing_mode="stretch_width")

You can use Folium in a Panel App

def get_map(lat=20.5936832, long=78.962883, zoom_start=5):
    return fm.Map(location=[lat,long], zoom_start=zoom_start)

map = get_map()

pn.panel(map, height=400)

Interactive Panel app using Folium#

Let build an interactive Panel application using Folium.

Lets define some data.

def get_df_aqi(lat_bounds=(10,30), long_bounds=(70,90), points_count=40):
    aqi = {
        "Latitude": [random.uniform(*lat_bounds) for _ in range(0,points_count)],
        "Longitude": [random.uniform(*long_bounds) for _ in range(0,points_count)],
        "AQI": [random.uniform(0,500) for _ in range(0,points_count)],
    }
    return pd.DataFrame(aqi)

df_aqi = get_df_aqi()
df_aqi.sample(5)
Latitude Longitude AQI
24 13.222713 81.799040 361.690498
21 17.272171 75.131666 263.187930
20 10.900339 87.011256 123.523165
35 24.417011 85.485553 134.706631
37 12.117465 88.166950 184.005271

Lets define some functionality to add the data to the map as circles

def add_aqi_circles(map, df_aqi):
    green_p1  = fm.map.FeatureGroup()
    yellow_p1 = fm.map.FeatureGroup()
    orange_p1 = fm.map.FeatureGroup()
    red_p1    = fm.map.FeatureGroup()
    purple_p1 = fm.map.FeatureGroup()
    maroon_p1 = fm.map.FeatureGroup()

    for _, row in df_aqi.iterrows():
        if row.AQI<50:
            feature_group = green_p1
            fill_color = "green"
        elif row.AQI < 100:
            feature_group = yellow_p1
            fill_color = "yellow"
        elif row.AQI < 150:
            feature_group = orange_p1
            fill_color = "orange"
        elif row.AQI < 200:
            feature_group = red_p1
            fill_color = "red"
        elif row.AQI < 300:
            feature_group = purple_p1
            fill_color='purple'
        else:
            feature_group = maroon_p1
            fill_color = "maroon"

        feature_group.add_child(
            fm.CircleMarker(
                [row.Latitude, row.Longitude],
                radius=10, 
                fill=True,
                fill_color=fill_color,
                fill_opacity=0.7
            )
        )

    map.add_child(green_p1)
    map.add_child(yellow_p1)
    map.add_child(orange_p1)
    map.add_child(red_p1)
    map.add_child(purple_p1)

add_aqi_circles(map, df_aqi)
pn.panel(map, height=400)

Lets put it all together into an interactive app where the user can select the number of data points to generate and display.

class PanelFoliumMap(param.Parameterized):
    points_count = param.Integer(20, bounds=(10,100))
        
    def __init__(self, **params):
        super().__init__(**params)
        self.map = get_map()
        self.folium_pane = pn.pane.plot.Folium(sizing_mode="stretch_both", min_height=500, margin=0)    
        self.view = pn.Column(
            self.param.points_count,
            self.folium_pane,
            sizing_mode="stretch_both", height=500
        )
        self._update_map()

    @param.depends("points_count", watch=True)
    def _update_map(self):
        self.map = get_map()
        df_aqi = get_df_aqi(points_count=self.points_count)
        add_aqi_circles(self.map, df_aqi)
        self.folium_pane.object = self.map

        
app = PanelFoliumMap()
app.view

App#

Lets wrap it into nice template that can be served via panel serve Folium.ipynb

pn.template.FastListTemplate(site="Panel", title="Folium", main=["This app demonstrates **how to use Folium with Panel**.", PanelFoliumMap().view]).servable();
This web page was generated from a Jupyter notebook and not all interactivity will work on this website. Right click to download and run locally for full Python-backed interactivity.

Download this notebook from GitHub (right-click to download).