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
25 28.376584 74.180266 150.622014
20 19.123690 71.954881 240.145334
8 15.220817 81.742920 141.086898
14 17.837122 83.732810 104.541209
15 16.603841 82.841220 48.624820

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