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
31 15.427279 79.610411 255.235242
13 19.845159 83.327662 209.950946
12 26.521024 82.430215 387.069775
26 21.104197 71.975439 92.836804
20 10.021149 82.319448 375.015065

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).