{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "Demonstrates the use of [`Folium`](https://python-visualization.github.io/folium/) in Panel." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "import folium as fm\n", "import pandas as pd\n", "import param\n", "import panel as pn\n", "import random\n", "pn.extension(sizing_mode=\"stretch_width\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "You can use `Folium` in a Panel App" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "def get_map(lat=20.5936832, long=78.962883, zoom_start=5):\n", " return fm.Map(location=[lat,long], zoom_start=zoom_start)\n", "\n", "map = get_map()\n", "\n", "pn.panel(map, height=400)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Interactive Panel app using Folium\n", "\n", "Let build an interactive Panel application using Folium.\n", "\n", "Lets **define some data**." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "def get_df_aqi(lat_bounds=(10,30), long_bounds=(70,90), points_count=40):\n", " aqi = {\n", " \"Latitude\": [random.uniform(*lat_bounds) for _ in range(0,points_count)],\n", " \"Longitude\": [random.uniform(*long_bounds) for _ in range(0,points_count)],\n", " \"AQI\": [random.uniform(0,500) for _ in range(0,points_count)],\n", " }\n", " return pd.DataFrame(aqi)\n", "\n", "df_aqi = get_df_aqi()\n", "df_aqi.sample(5)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Lets define some functionality to **add the data to the map** as circles" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "def add_aqi_circles(map, df_aqi):\n", " green_p1 = fm.map.FeatureGroup()\n", " yellow_p1 = fm.map.FeatureGroup()\n", " orange_p1 = fm.map.FeatureGroup()\n", " red_p1 = fm.map.FeatureGroup()\n", " purple_p1 = fm.map.FeatureGroup()\n", " maroon_p1 = fm.map.FeatureGroup()\n", "\n", " for _, row in df_aqi.iterrows():\n", " if row.AQI<50:\n", " feature_group = green_p1\n", " fill_color = \"green\"\n", " elif row.AQI < 100:\n", " feature_group = yellow_p1\n", " fill_color = \"yellow\"\n", " elif row.AQI < 150:\n", " feature_group = orange_p1\n", " fill_color = \"orange\"\n", " elif row.AQI < 200:\n", " feature_group = red_p1\n", " fill_color = \"red\"\n", " elif row.AQI < 300:\n", " feature_group = purple_p1\n", " fill_color='purple'\n", " else:\n", " feature_group = maroon_p1\n", " fill_color = \"maroon\"\n", "\n", " feature_group.add_child(\n", " fm.CircleMarker(\n", " [row.Latitude, row.Longitude],\n", " radius=10, \n", " fill=True,\n", " fill_color=fill_color,\n", " fill_opacity=0.7\n", " )\n", " )\n", "\n", " map.add_child(green_p1)\n", " map.add_child(yellow_p1)\n", " map.add_child(orange_p1)\n", " map.add_child(red_p1)\n", " map.add_child(purple_p1)\n", "\n", "add_aqi_circles(map, df_aqi)\n", "pn.panel(map, height=400)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Lets put it all together into an **interactive app** where the user can select the number of data points to generate and display." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "class PanelFoliumMap(param.Parameterized):\n", " points_count = param.Integer(20, bounds=(10,100))\n", " \n", " def __init__(self, **params):\n", " super().__init__(**params)\n", " self.map = get_map()\n", " self.folium_pane = pn.pane.plot.Folium(sizing_mode=\"stretch_both\", min_height=500, margin=0) \n", " self.view = pn.Column(\n", " self.param.points_count,\n", " self.folium_pane,\n", " sizing_mode=\"stretch_both\", height=500\n", " )\n", " self._update_map()\n", "\n", " @param.depends(\"points_count\", watch=True)\n", " def _update_map(self):\n", " self.map = get_map()\n", " df_aqi = get_df_aqi(points_count=self.points_count)\n", " add_aqi_circles(self.map, df_aqi)\n", " self.folium_pane.object = self.map\n", "\n", " \n", "app = PanelFoliumMap()\n", "app.view" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## App\n", "\n", "Lets wrap it into nice template that can be served via `panel serve Folium.ipynb`" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "pn.template.FastListTemplate(site=\"Panel\", title=\"Folium\", main=[\"This app demonstrates **how to use Folium with Panel**.\", PanelFoliumMap().view]).servable();" ] } ], "metadata": { "kernelspec": { "display_name": "Python 3", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.8.4" } }, "nbformat": 4, "nbformat_minor": 4 }