{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# ipyleaflet: Interactive maps\n", "\n", "## A Jupyter - LeafletJS bridge\n", "\n", "## https://github.com/jupyter-widgets/ipyleaflet\n", "\n", "\n", "ipyleaflet is a jupyter interactive widget library which provides interactive maps to the Jupyter notebook.\n", "\n", "- MIT Licensed\n", "\n", "**Installation:**\n", "\n", "```bash\n", "conda install -c conda-forge ipyleaflet\n", "```" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "from __future__ import print_function\n", "\n", "from ipyleaflet import (\n", " Map,\n", " Marker, MarkerCluster,\n", " TileLayer, ImageOverlay,\n", " Polyline, Polygon, Rectangle, Circle, CircleMarker,\n", " Popup,\n", " GeoJSON,\n", " SplitMapControl, WidgetControl,\n", " basemaps,\n", " basemap_to_tiles\n", ")\n", "\n", "from ipywidgets import HTML" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "center = [34.6252978589571, -77.34580993652344]\n", "zoom = 10" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "m = Map(center=center, zoom=zoom)\n", "m" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "m.interact(zoom=(5, 10, 1))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# jupyterlab-sidecar: A sidecar output widget for JupyterLab\n", "\n", "## https://github.com/jupyter-widgets/jupyterlab-sidecar" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "from sidecar import Sidecar\n", "\n", "sc = Sidecar(title='Map Output')\n", "with sc:\n", " display(m)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "m.clear_layers()" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "m.add_layer(basemaps.Esri.DeLorme)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "print(m.center)\n", "print(m.zoom)\n", "print(m.bounds)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Marker" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "mark = Marker(location=m.center)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "mark.visible" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "m += mark" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "mark.interact(opacity=(0.0,1.0,0.01))" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "mark.visible" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "mark.visible = False" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "mark.visible = True" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Popup\n", "\n", "The popup is displayed when you click on the marker. You can add ANY widget as a popup for the marker, from simple HTMLWidget to plots using bqplot." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "from ipywidgets import FloatSlider, link\n", "\n", "slider = FloatSlider(value=1.0, min=0.0, max=1.0)\n", "link((mark, 'opacity'), (slider, 'value'))\n", "\n", "mark.popup = slider" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Marker Cluster\n", "\n", "Markers can be clustered depending on the zoom level." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "xscale = 5\n", "yscale = 10\n", "\n", "x = [m.center[0] + i * xscale * .05 for i in (-1,0,1)]\n", "y = [m.center[1] + i * yscale * .05 for i in (-1,0,1)]\n", "\n", "from itertools import product\n", "locations = product(x, y)\n", "markers = [Marker(location=loc) for loc in locations]" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The `MarkerCluster` will automatically handle clustering and the zoom level changes." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "marker_cluster = MarkerCluster(markers=markers)\n", "m += marker_cluster" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Controls" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# The following NASA images need a zoom level <= 9\n", "if m.zoom > 9:\n", " m.zoom = 9\n", "\n", "control = SplitMapControl(\n", " left_layer=basemap_to_tiles(basemaps.NASAGIBS.ModisTerraTrueColorCR, \"2017-11-11\") , \n", " right_layer=basemap_to_tiles(basemaps.NASAGIBS.ModisAquaBands721CR, \"2017-11-11\")\n", ")\n", "m.add_control(control)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "m.remove_control(control)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "from ipywidgets import IntSlider, Button, link\n", "\n", "button = Button(description='Goto NYC')\n", "\n", "def goto_nyc(*args, **kwargs):\n", " # NYC: 40.7128° N, 74.0060° W\n", " m.center = (40.7128, -74.0060)\n", " m.zoom = 9\n", "\n", "button.on_click(goto_nyc)\n", "\n", "wid_control = WidgetControl(widget=button, position='bottomright')\n", "m.add_control(wid_control)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "m.remove_control(wid_control)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# Advanced example" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "from ipywidgets import Text, HTML, HBox\n", "from ipyleaflet import GeoJSON, WidgetControl, Map \n", "import json" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "m = Map(center = (43,-100), zoom = 4)\n", "\n", "geo_json_data = json.load(open('us-states-density-colored.json'))\n", "geojson = GeoJSON(data=geo_json_data, hover_style={'color': 'black', 'dashArray': '5, 5', 'weight': 2})\n", "m.add_layer(geojson)\n", "\n", "html = HTML('''\n", "