|
8 | 8 | "When it comes to visualizing geospatial data with/on maps with Python, a great number of tools and techniques\n", |
9 | 9 | "are available. In this lesson we will explore several of these:\n", |
10 | 10 | "\n", |
11 | | - "* [Folium](https://github.com/python-visualization/folium)\n", |
12 | | - "* [ipyleaflet](https://ipyleaflet.readthedocs.io)\n", |
13 | | - "* [Bokeh](https://bokeh.pydata.org)\n", |
14 | | - "* [pydeck](https://pydeck.gl) - optional\n" |
| 11 | + "* [Folium](#Folium)\n", |
| 12 | + "* [ipyleaflet](#ipyleaflet)\n", |
| 13 | + "* [Bokeh](#Bokeh)\n", |
| 14 | + "* [pydeck](#pydeck)\n" |
15 | 15 | ] |
16 | 16 | }, |
17 | 17 | { |
|
21 | 21 | "## Folium\n", |
22 | 22 | "Whenever you visit a website that has some kind of interactive map, it\n", |
23 | 23 | "is quite probable that you are witnessing a map that has been made with\n", |
24 | | - "a JavaScript library called [Leaflet](http://leafletjs.com). The\n", |
25 | | - "other popular library you might encounter is\n", |
26 | | - "[OpenLayers](https://openlayers.org).\n", |
| 24 | + "a JavaScript library called [Leaflet](http://leafletjs.com). Other popular libraries you may encounter are\n", |
| 25 | + "[OpenLayers](https://openlayers.org) and [maplibre](https://maplibre.org/).\n", |
27 | 26 | "\n", |
28 | 27 | "The Python module \n", |
29 | 28 | "[Folium](https://github.com/python-visualization/folium) makes\n", |
30 | 29 | "it possible to visualize data that has been manipulated in Python on an\n", |
31 | | - "interactive Leaflet map.\n", |
| 30 | + "interactive Leaflet map in a jupyter notebook or website generated from python code.\n", |
32 | 31 | "\n", |
33 | 32 | "### Basics\n", |
34 | 33 | "We will start with the most minimal map using the default OpenStreetMap base map.\n", |
|
158 | 157 | "metadata": {}, |
159 | 158 | "source": [ |
160 | 159 | "And [open this map with overlay here](test/07-folium-2.html). \n", |
161 | | - "\n", |
162 | | - "Much more is possible with Folium, we just scratched the surface here!" |
| 160 | + "\n" |
| 161 | + ] |
| 162 | + }, |
| 163 | + { |
| 164 | + "cell_type": "markdown", |
| 165 | + "metadata": {}, |
| 166 | + "source": [ |
| 167 | + "### Folium and Streamlit\n", |
| 168 | + "Folium can also be [combined with Streamlit](https://folium.streamlit.app/). \n", |
| 169 | + "[Streamlit](https://streamlit.io) is a platform to create interactive web apps for your python data scripts.\n", |
| 170 | + "\n" |
163 | 171 | ] |
164 | 172 | }, |
165 | 173 | { |
|
170 | 178 | } |
171 | 179 | }, |
172 | 180 | "source": [ |
173 | | - "## Interactive maps in the Jupyter notebook with ipyleaflet\n", |
174 | | - "ipyleaflet is a Jupyter/Leaflet bridge enabling interactive maps in the Jupyter notebook.\n", |
175 | | - "(Although one can always save the results and use these maps in non-Jupyter contexts!).\n", |
176 | | - "\n", |
177 | | - "`ipyleaflet` is based on [ipywidgets](https://ipywidgets.readthedocs.io).\n", |
178 | | - "ipywidgets are interactive HTML widgets for Jupyter notebooks and the IPython kernel.\n", |
| 181 | + "## ipyleaflet\n", |
| 182 | + "[ipyleaflet](https://ipyleaflet.readthedocs.io) provides similar functionality as folium, however because\n", |
| 183 | + "it is based on [ipywidgets](https://ipywidgets.readthedocs.io), it integrates with other components from\n", |
| 184 | + "the ipywidgets ecosystem (sliders, datagrids, tabs).\n", |
179 | 185 | "\n", |
180 | 186 | "Links:\n", |
181 | 187 | "\n", |
|
444 | 450 | "source": [ |
445 | 451 | "## Bokeh\n", |
446 | 452 | "\n", |
447 | | - "Bokeh is a very powerful framework to produce powerful maps in combination\n", |
448 | | - "with data. With Geopandas and Bokeh one can produce nice looking interactive maps like in the image below:\n", |
| 453 | + "Bokeh is a powerful framework to produce tailored interactive map and data visualisations.\n", |
| 454 | + "Map features are limited compared to Folium, but there are more options to tailor the behaviour.\n", |
| 455 | + "Bokeh provides mechanisms to interact with a server side application. With Geopandas and Bokeh\n", |
| 456 | + "one can produce a nice looking interactive map like in the image below:\n", |
449 | 457 | "\n", |
450 | 458 | "\n", |
451 | 459 | "*Interactive Map with Bokeh and GeoPandas - Source: [CSC L6](https://automating-gis-processes.github.io/CSC/lessons/L6/interactive-map-bokeh.html)*\n" |
|
886 | 894 | "cell_type": "markdown", |
887 | 895 | "metadata": {}, |
888 | 896 | "source": [ |
889 | | - "## pydeck - OPTIONAL\n", |
890 | | - "\n", |
891 | | - "[pydeck](https://pydeck.gl/) is a WebGL2-powered, highly performant large-scale data visualization framework.\n", |
892 | | - "We leave it you to explore pydeck through [its documentation](https://pydeck.gl/).\n", |
893 | | - "\n", |
894 | | - "pydeck is part of [deck.gl](https://deck.gl/).\n", |
895 | | - "\n", |
896 | | - "\n", |
897 | | - "\n", |
898 | | - "From their [GitHub README](https://github.com/visgl/deck.gl):\n", |
| 897 | + "## pydeck\n", |
899 | 898 | "\n", |
900 | | - "*\"deck.gl is designed to simplify high-performance, WebGL-based visualization of large data sets.\n", |
901 | | - "Users can quickly get impressive visual results with minimal effort by composing existing layers,\n", |
902 | | - "or leverage deck.gl's extensible architecture to address custom needs.*\n", |
| 899 | + "Up till this point we've looked at 2D data visualisations. With [pydeck](https://pydeck.gl/)\n", |
| 900 | + "we switch to WebGL-powered data visualization, including 3D and vector tiles.\n", |
| 901 | + "pydeck is a python wrapper for the [deck.gl](https://deck.gl/) javascript library.\n", |
| 902 | + "deck.gl visualisations typically use a vector tile background (from [mapbox](https://mapbox.com), [maptiler](https://www.maptiler.com/), or similar)\n", |
903 | 903 | "\n", |
904 | | - "*deck.gl maps **data** (usually an array of JSON objects) into a stack of visual **layers** - e.g. icons, polygons, texts; and look at them with **views**: e.g. map, first-person, orthographic.*\n", |
| 904 | + "\n", |
905 | 905 | "\n", |
906 | | - "*deck.gl handles a number of challenges out of the box:*\n", |
| 906 | + "The code snippet below creates a deck.gl view based on some sample data with tooltips.\n" |
| 907 | + ] |
| 908 | + }, |
| 909 | + { |
| 910 | + "cell_type": "code", |
| 911 | + "execution_count": 0, |
| 912 | + "metadata": { |
| 913 | + "scrolled": true |
| 914 | + }, |
| 915 | + "outputs": [], |
| 916 | + "source": [ |
| 917 | + "import pydeck as pdk\n", |
| 918 | + "import pandas as pd\n", |
| 919 | + "\n", |
| 920 | + "# Sample data: 6 locations with population\n", |
| 921 | + "data = pd.DataFrame({\n", |
| 922 | + " 'lat': [43.5081, 43.2967, 43.0500, 43.3438, 42.6507, 42.9228],\n", |
| 923 | + " 'lon': [16.4402, 17.0177, 17.4333, 17.8078, 18.0944, 17.6158],\n", |
| 924 | + " 'pop': [160000 , 13000, 6500, 105000, 41000, 4000],\n", |
| 925 | + " 'city': ['Split', 'Makarska', 'Ploče', 'Mostar', 'Dubrovnik', 'Neum']\n", |
| 926 | + "})\n", |
| 927 | + "\n", |
| 928 | + "# Define a scatterplot layer\n", |
| 929 | + "layer = pdk.Layer(\n", |
| 930 | + " 'ScatterplotLayer',\n", |
| 931 | + " data=data,\n", |
| 932 | + " get_position='[lon, lat]',\n", |
| 933 | + " get_radius='pop / 10',\n", |
| 934 | + " get_fill_color='[180, 0, 200, 140]',\n", |
| 935 | + " pickable=True\n", |
| 936 | + ")\n", |
907 | 937 | "\n", |
908 | | - "* *Performant rendering and updating of large data sets*\n", |
909 | | - "* *Interactive event handling such as picking, highlighting and filtering*\n", |
910 | | - "* *Cartographic projections and integration with major basemap providers*\n", |
911 | | - "* *A catalog of proven, well-tested layers*\n", |
| 938 | + "# Define map view\n", |
| 939 | + "view_state = pdk.ViewState(\n", |
| 940 | + " latitude=42.7,\n", |
| 941 | + " longitude=16.8,\n", |
| 942 | + " zoom=7,\n", |
| 943 | + " pitch=30,\n", |
| 944 | + " bearing=10\n", |
| 945 | + ")\n", |
912 | 946 | "\n", |
913 | | - "*Deck.gl is designed to be highly customizable.*\n", |
914 | | - "*All layers come with flexible APIs to allow programmatic control of each aspect of the rendering.*\n", |
915 | | - "*All core classes such are easily extendable by the users to address custom use cases.\"*\n", |
| 947 | + "# Render view\n", |
| 948 | + "deck = pdk.Deck(\n", |
| 949 | + " layers=[layer],\n", |
| 950 | + " initial_view_state=view_state,\n", |
| 951 | + " tooltip={\"text\": \"{city}\"}\n", |
| 952 | + ")\n", |
916 | 953 | "\n", |
917 | | - "deck.gl comes in several flavors (programming languages): JavaScript (`deck.gl`) and Python (`pydeck`)." |
| 954 | + "deck.show()" |
918 | 955 | ] |
919 | 956 | }, |
920 | 957 | { |
|
0 commit comments