{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "Quickstart\n", "==========\n", "\n", "\n", "Getting Started\n", "---------------\n", "\n", "\n", "To create a base map, simply pass your starting coordinates to Folium:" ] }, { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [], "source": [ "import folium\n", "\n", "\n", "m = folium.Map(location=[45.5236, -122.6750])" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "To display it in a Jupyter notebook, simply ask for the object representation:" ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
" ], "text/plain": [ "" ] }, "execution_count": 2, "metadata": {}, "output_type": "execute_result" } ], "source": [ "m" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "to save it in a file," ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [], "source": [ "m.save('index.html')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The default tiles are set to `OpenStreetMap`, but `Stamen Terrain`, `Stamen Toner`, `Mapbox Bright`, and `Mapbox Control Room`, and many others tiles are built in." ] }, { "cell_type": "code", "execution_count": 4, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
" ], "text/plain": [ "" ] }, "execution_count": 4, "metadata": {}, "output_type": "execute_result" } ], "source": [ "folium.Map(\n", " location=[45.5236, -122.6750],\n", " tiles='Stamen Toner',\n", " zoom_start=13\n", ")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "One can use `Cloudmade` or `Mapbox` custom tilesets--simply pass your key to the `API_key` keyword:\n", "\n", "```python\n", "folium.Map(location=[45.5236, -122.6750],\n", " tiles='Mapbox',\n", " API_key='your.API.key')\n", "```\n", "\n", "Lastly, Folium supports passing any `leaflet.js` compatible custom tileset:\n", "\n", "```python\n", "folium.Map(location=[45.372, -121.6972],\n", " zoom_start=12,\n", " tiles='http://{s}.tiles.yourtiles.com/{z}/{x}/{y}.png',\n", " attr='My Data Attribution')\n", "```" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Markers\n", "-------\n", "\n", "There are numerous marker types, starting with a simple `Leaflet`\n", "style location marker with a popup and tooltip `HTML`." ] }, { "cell_type": "code", "execution_count": 5, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
" ], "text/plain": [ "" ] }, "execution_count": 5, "metadata": {}, "output_type": "execute_result" } ], "source": [ "m = folium.Map(\n", " location=[45.372, -121.6972],\n", " zoom_start=12,\n", " tiles='Stamen Terrain'\n", ")\n", "\n", "tooltip = 'Click me!'\n", "\n", "folium.Marker([45.3288, -121.6625], popup='Mt. Hood Meadows', tooltip=tooltip).add_to(m)\n", "folium.Marker([45.3311, -121.7113], popup='Timberline Lodge', tooltip=tooltip).add_to(m)\n", "\n", "m" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "There is built in support for colors and marker icon types from bootstrap." ] }, { "cell_type": "code", "execution_count": 6, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
" ], "text/plain": [ "" ] }, "execution_count": 6, "metadata": {}, "output_type": "execute_result" } ], "source": [ "m = folium.Map(\n", " location=[45.372, -121.6972],\n", " zoom_start=12,\n", " tiles='Stamen Terrain'\n", ")\n", "\n", "folium.Marker(\n", " location=[45.3288, -121.6625],\n", " popup='Mt. Hood Meadows',\n", " icon=folium.Icon(icon='cloud')\n", ").add_to(m)\n", "\n", "folium.Marker(\n", " location=[45.3311, -121.7113],\n", " popup='Timberline Lodge',\n", " icon=folium.Icon(color='green')\n", ").add_to(m)\n", "\n", "folium.Marker(\n", " location=[45.3300, -121.6823],\n", " popup='Some Other Location',\n", " icon=folium.Icon(color='red', icon='info-sign')\n", ").add_to(m)\n", "\n", "\n", "m" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Leaflet's `Circle` and `CircleMarker`, implemented to reflect radii in units of meters and pixels respectively, are available as `features`. See the `features.py` for more options." ] }, { "cell_type": "code", "execution_count": 7, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
" ], "text/plain": [ "" ] }, "execution_count": 7, "metadata": {}, "output_type": "execute_result" } ], "source": [ "m = folium.Map(\n", " location=[45.5236, -122.6750],\n", " tiles='Stamen Toner',\n", " zoom_start=13\n", ")\n", "\n", "folium.Circle(\n", " radius=100,\n", " location=[45.5244, -122.6699],\n", " popup='The Waterfront',\n", " color='crimson',\n", " fill=False,\n", ").add_to(m)\n", "\n", "folium.CircleMarker(\n", " location=[45.5215, -122.6261],\n", " radius=50,\n", " popup='Laurelhurst Park',\n", " color='#3186cc',\n", " fill=True,\n", " fill_color='#3186cc'\n", ").add_to(m)\n", "\n", "\n", "m" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "a convenience function to enable lat/lng popovers:" ] }, { "cell_type": "code", "execution_count": 8, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
" ], "text/plain": [ "" ] }, "execution_count": 8, "metadata": {}, "output_type": "execute_result" } ], "source": [ "m = folium.Map(\n", " location=[46.1991, -122.1889],\n", " tiles='Stamen Terrain',\n", " zoom_start=13\n", ")\n", "\n", "m.add_child(folium.LatLngPopup())\n", "\n", "\n", "m" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "and click-for-marker functionality for on-the-fly placement of markers:" ] }, { "cell_type": "code", "execution_count": 9, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
" ], "text/plain": [ "" ] }, "execution_count": 9, "metadata": {}, "output_type": "execute_result" } ], "source": [ "m = folium.Map(\n", " location=[46.8527, -121.7649],\n", " tiles='Stamen Terrain',\n", " zoom_start=13\n", ")\n", "\n", "folium.Marker(\n", " [46.8354, -121.7325],\n", " popup='Camp Muir'\n", ").add_to(m)\n", "\n", "m.add_child(folium.ClickForMarker(popup='Waypoint'))\n", "\n", "\n", "m" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Vincent/Vega and Altair/VegaLite Markers\n", "\n", "`folium` enables passing any HTML object as a popup,\n", "including [`bokeh`](https://bokeh.pydata.org/en/latest/) plots,\n", "but there is a built-in support for [vincent](https://github.com/wrobstory/vincent) and [altair](https://altair-viz.github.io) visualizations to any marker type, with the visualization as the popover." ] }, { "cell_type": "code", "execution_count": 10, "metadata": {}, "outputs": [], "source": [ "import os\n", "\n", "vis1 = os.path.join('data', 'vis1.json')\n", "vis2 = os.path.join('data', 'vis2.json')\n", "vis3 = os.path.join('data', 'vis3.json')" ] }, { "cell_type": "code", "execution_count": 11, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
" ], "text/plain": [ "" ] }, "execution_count": 11, "metadata": {}, "output_type": "execute_result" } ], "source": [ "import json\n", "\n", "\n", "m = folium.Map(\n", " location=[46.3014, -123.7390],\n", " zoom_start=7,\n", " tiles='Stamen Terrain'\n", ")\n", "\n", "folium.Marker(\n", " location=[47.3489, -124.708],\n", " popup=folium.Popup(max_width=450).add_child(\n", " folium.Vega(json.load(open(vis1)), width=450, height=250))\n", ").add_to(m)\n", "\n", "folium.Marker(\n", " location=[44.639, -124.5339],\n", " popup=folium.Popup(max_width=450).add_child(\n", " folium.Vega(json.load(open(vis2)), width=450, height=250))\n", ").add_to(m)\n", "\n", "folium.Marker(\n", " location=[46.216, -124.1280],\n", " popup=folium.Popup(max_width=450).add_child(\n", " folium.Vega(json.load(open(vis3)), width=450, height=250))\n", ").add_to(m)\n", "\n", "\n", "m" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "For more information about popups, please visit [Popups.ipynb](https://nbviewer.jupyter.org/github/python-visualization/folium/blob/master/examples/Popups.ipynb)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## GeoJSON/TopoJSON Overlays\n", "\n", "Both GeoJSON and TopoJSON layers can be passed to the map as an overlay, and multiple layers can be visualized on the same map:" ] }, { "cell_type": "code", "execution_count": 12, "metadata": { "scrolled": false }, "outputs": [ { "data": { "text/html": [ "
" ], "text/plain": [ "" ] }, "execution_count": 12, "metadata": {}, "output_type": "execute_result" } ], "source": [ "antarctic_ice_edge = os.path.join('data', 'antarctic_ice_edge.json')\n", "antarctic_ice_shelf_topo = os.path.join('data', 'antarctic_ice_shelf_topo.json')\n", "\n", "m = folium.Map(\n", " location=[-59.1759, -11.6016],\n", " tiles='Mapbox Bright',\n", " zoom_start=2\n", ")\n", "\n", "folium.GeoJson(\n", " antarctic_ice_edge,\n", " name='geojson'\n", ").add_to(m)\n", "\n", "folium.TopoJson(\n", " open(antarctic_ice_shelf_topo),\n", " 'objects.antarctic_ice_shelf',\n", " name='topojson'\n", ").add_to(m)\n", "\n", "folium.LayerControl().add_to(m)\n", "\n", "\n", "m" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Choropleth maps\n", "\n", "Choropleth can be easily created by binding the data between Pandas DataFrames/Series and Geo/TopoJSON geometries. [Color Brewer](http://colorbrewer2.org/) sequential color schemes are built-in to the library, and can be passed to quickly visualize different combinations." ] }, { "cell_type": "code", "execution_count": 13, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
" ], "text/plain": [ "" ] }, "execution_count": 13, "metadata": {}, "output_type": "execute_result" } ], "source": [ "import pandas as pd\n", "\n", "state_geo = os.path.join('data', 'us-states.json')\n", "\n", "state_unemployment = os.path.join('data', 'US_Unemployment_Oct2012.csv')\n", "state_data = pd.read_csv(state_unemployment)\n", "\n", "m = folium.Map(location=[48, -102], zoom_start=3)\n", "\n", "folium.Choropleth(\n", " geo_data=state_geo,\n", " name='choropleth',\n", " data=state_data,\n", " columns=['State', 'Unemployment'],\n", " key_on='feature.id',\n", " fill_color='YlGn',\n", " fill_opacity=0.7,\n", " line_opacity=0.2,\n", " legend_name='Unemployment Rate (%)'\n", ").add_to(m)\n", "\n", "folium.LayerControl().add_to(m)\n", "\n", "m" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The legend on the upper right is automatically generated for your values using 6 same sized bins.\n", "Passing your own bins (number or list) is simple:" ] }, { "cell_type": "code", "execution_count": 14, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
" ], "text/plain": [ "" ] }, "execution_count": 14, "metadata": {}, "output_type": "execute_result" } ], "source": [ "bins = list(state_data['Unemployment'].quantile([0, 0.25, 0.5, 0.75, 1]))\n", "\n", "m = folium.Map(location=[48, -102], zoom_start=3)\n", "\n", "folium.Choropleth(\n", " geo_data=state_geo,\n", " data=state_data,\n", " columns=['State', 'Unemployment'],\n", " key_on='feature.id',\n", " fill_color='BuPu',\n", " fill_opacity=0.7,\n", " line_opacity=0.5,\n", " legend_name='Unemployment Rate (%)',\n", " bins=bins,\n", " reset=True\n", ").add_to(m)\n", "\n", "m" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "By binding data via the Pandas DataFrame, different datasets can be quickly visualized." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Styling function\n", "\n", "`GeoJson` and `TopoJson` features accepts `style_function` to allow for further custimization of the map.\n", "Take a look at the use examples below." ] }, { "cell_type": "code", "execution_count": 15, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
" ], "text/plain": [ "" ] }, "execution_count": 15, "metadata": {}, "output_type": "execute_result" } ], "source": [ "import branca\n", "\n", "county_data = os.path.join('data', 'us_county_data.csv')\n", "county_geo = os.path.join('data', 'us_counties_20m_topo.json')\n", "\n", "df = pd.read_csv(county_data, na_values=[' '])\n", "\n", "\n", "colorscale = branca.colormap.linear.YlOrRd_09.scale(0, 50e3)\n", "employed_series = df.set_index('FIPS_Code')['Employed_2011']\n", "\n", "\n", "def style_function(feature):\n", " employed = employed_series.get(int(feature['id'][-5:]), None)\n", " return {\n", " 'fillOpacity': 0.5,\n", " 'weight': 0,\n", " 'fillColor': '#black' if employed is None else colorscale(employed)\n", " }\n", "\n", "\n", "m = folium.Map(\n", " location=[48, -102],\n", " tiles='cartodbpositron',\n", " zoom_start=3\n", ")\n", "\n", "folium.TopoJson(\n", " open(county_geo),\n", " 'objects.us_counties_20m',\n", " style_function=style_function\n", ").add_to(m)\n", "\n", "\n", "m" ] }, { "cell_type": "code", "execution_count": 16, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
" ], "text/plain": [ "" ] }, "execution_count": 16, "metadata": {}, "output_type": "execute_result" } ], "source": [ "colorscale = branca.colormap.linear.YlGnBu_09.scale(0, 30)\n", "\n", "employed_series = df.set_index('FIPS_Code')['Unemployment_rate_2011']\n", "\n", "\n", "def style_function(feature):\n", " employed = employed_series.get(int(feature['id'][-5:]), None)\n", " return {\n", " 'fillOpacity': 0.5,\n", " 'weight': 0,\n", " 'fillColor': '#black' if employed is None else colorscale(employed)\n", " }\n", "\n", "\n", "m = folium.Map(\n", " location=[48, -102],\n", " tiles='cartodbpositron',\n", " zoom_start=3\n", ")\n", "\n", "folium.TopoJson(\n", " open(county_geo),\n", " 'objects.us_counties_20m',\n", " style_function=style_function\n", ").add_to(m)\n", "\n", "\n", "m" ] }, { "cell_type": "code", "execution_count": 17, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
" ], "text/plain": [ "" ] }, "execution_count": 17, "metadata": {}, "output_type": "execute_result" } ], "source": [ "colorscale = branca.colormap.linear.PuRd_09.scale(0, 100000)\n", "\n", "employed_series = df.set_index('FIPS_Code')['Median_Household_Income_2011'].dropna()\n", "\n", "\n", "def style_function(feature):\n", " employed = employed_series.get(int(feature['id'][-5:]), None)\n", " return {\n", " 'fillOpacity': 0.5,\n", " 'weight': 0,\n", " 'fillColor': '#black' if employed is None else colorscale(employed)\n", " }\n", "\n", "\n", "m = folium.Map(\n", " location=[48, -102],\n", " tiles='cartodbpositron',\n", " zoom_start=3\n", ")\n", "\n", "folium.TopoJson(\n", " open(county_geo),\n", " 'objects.us_counties_20m',\n", " style_function=style_function\n", ").add_to(m)\n", "\n", "\n", "m" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "For more examples and use cases please take a look at the gallery:\n", "\n", "https://nbviewer.jupyter.org/github/python-visualization/folium_contrib/tree/master/notebooks/" ] } ], "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.7.1" }, "toc": { "base_numbering": 1, "nav_menu": {}, "number_sections": true, "sideBar": true, "skip_h1_title": false, "title_cell": "Table of Contents", "title_sidebar": "Contents", "toc_cell": false, "toc_position": {}, "toc_section_display": true, "toc_window_display": false } }, "nbformat": 4, "nbformat_minor": 1 }