{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# Folium" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "[Folium](https://python-visualization.github.io/folium/) es un módulo de Python que crea mapas para la Web mediante la generación de código fuente en el lenguaje [JavaScript](https://developer.mozilla.org/en-US/docs/Web/JavaScript) para la biblioteca [Leaflet](https://leafletjs.com/), la cual es una de las más utilizadas para la programación de mapas interactivos. Los mapas y sus componentes (ej. capas, marcadores, controles) se construyen y configuran mediante las [clases de Folium y sus métodos asociados](https://python-visualization.github.io/folium/modules.html)." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Instalación\n", "Para instalar el Folium mediante **Conda**, deben ejecutarse las siguientes instrucciones desde la línea de comandos del sistema operativo (puede utilizarse la línea de comandos de Anaconda):\n", "\n", "```\n", "conda install folium -c conda-forge\n", "```" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Importación" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "El módulo Folium debe importarse mediante la sentencia **import**. Esta sentencia debe ejecutarse antes de invocar a cualquier clase o método de **Folium**." ] }, { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "0.11.0\n" ] } ], "source": [ "import folium\n", "\n", "# Impresión de la versión de Folium\n", "print(folium.__version__)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Ejemplos de uso\n", "A continuación se proporcionan algunos ejemplos de uso de las clases y métodos de Folium." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Clase [Map](https://python-visualization.github.io/folium/modules.html#folium.folium.Map)\n", "Esta clase crea un mapa de acuerdo con diferentes parámetros de inicialización (centro, tamaño, mapa base, etc.)." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### Parámetros de inicialización de un mapa" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "El centro de un mapa se especifica mediante el parámetro **location**." ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
Make this Notebook Trusted to load map: File -> Trust Notebook
" ], "text/plain": [ "" ] }, "execution_count": 2, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# Creación de un mapa con un centro (x, y)\n", "m = folium.Map(location=[10, -84])\n", "\n", "# Despliegue del mapa en el notebook\n", "m" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Los parámetros **width** y **height** se utilizan para especificar respectivamente el ancho y el largo del mapa, en pixeles." ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
Make this Notebook Trusted to load map: File -> Trust Notebook
" ], "text/plain": [ "" ] }, "execution_count": 3, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# Especificación del ancho y del largo (en pixeles) del mapa\n", "m = folium.Map(\n", " location=[10, -84], \n", " width=650, height=400)\n", "\n", "m" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "También es posible establecer un nivel inicial de acercamiento (_zoom_) del mapa mediante un número entre 1 (menor acercamiento) y 20 (mayor acercamiento). Para esto, se utiliza el parámetro **zoom_start**." ] }, { "cell_type": "code", "execution_count": 4, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
Make this Notebook Trusted to load map: File -> Trust Notebook
" ], "text/plain": [ "" ] }, "execution_count": 4, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# Especificación del nivel inicial de acercamiento (zoom)\n", "m = folium.Map(\n", " location=[10, -84], \n", " width=650, height=400, \n", " zoom_start=7)\n", "\n", "m" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### Selección del mapa base" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "##### Mapas predeterminados" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Por defecto, Folium utiliza [OpenStreetMap](https://www.openstreetmap.org/) como mapa base. Pueden elegirse otros mapas base mediante el parámetro **tiles**, el cual tiene un conjunto de valores predeterminados:\n", "\n", "- “OpenStreetMap”\n", "- “Mapbox Bright”\n", "- “Mapbox Control Room”\n", "- “Stamen” (\"Terrain\", \"Toner\" y \"Watercolor\")\n", "- “Cloudmade” (Requiere una llave del API)\n", "- “Mapbox” (Requiere una llave del API)\n", "- “CartoDB” (\"positron\" y \"dark_matter\")" ] }, { "cell_type": "code", "execution_count": 5, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
Make this Notebook Trusted to load map: File -> Trust Notebook
" ], "text/plain": [ "" ] }, "execution_count": 5, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# Mapa de Stamen Terrain\n", "m = folium.Map(\n", " location=[10, -84], \n", " width=650, height=400, \n", " zoom_start=5, \n", " tiles='Stamen Terrain')\n", "m" ] }, { "cell_type": "code", "execution_count": 6, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
Make this Notebook Trusted to load map: File -> Trust Notebook
" ], "text/plain": [ "" ] }, "execution_count": 6, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# Mapa de Stamen Toner\n", "m = folium.Map(\n", " location=[10, -84], \n", " width=650, height=400, \n", " zoom_start=7, \n", " tiles='Stamen Toner')\n", "\n", "m" ] }, { "cell_type": "code", "execution_count": 7, "metadata": { "scrolled": true }, "outputs": [ { "data": { "text/html": [ "
Make this Notebook Trusted to load map: File -> Trust Notebook
" ], "text/plain": [ "" ] }, "execution_count": 7, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# Mapa de Stamen Watercolor\n", "m = folium.Map(\n", " location=[10, -84], \n", " width=650, height=400, \n", " zoom_start=7, \n", " tiles='Stamen Watercolor')\n", "\n", "m" ] }, { "cell_type": "code", "execution_count": 8, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
Make this Notebook Trusted to load map: File -> Trust Notebook
" ], "text/plain": [ "" ] }, "execution_count": 8, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# Mapa de CartoDB positron\n", "m = folium.Map(\n", " location=[10, -84], \n", " width=650, height=400, \n", " zoom_start=7, \n", " tiles='CartoDB positron')\n", "\n", "m" ] }, { "cell_type": "code", "execution_count": 9, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
Make this Notebook Trusted to load map: File -> Trust Notebook
" ], "text/plain": [ "" ] }, "execution_count": 9, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# Mapa de CartoDB dark_matter\n", "m = folium.Map(\n", " location=[10, -84], \n", " width=650, height=400, \n", " zoom_start=7, \n", " tiles='CartoDB dark_matter')\n", "\n", "m" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "##### Conjuntos personalizados de teselas" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Además de los valores predeterminados, el parámetro **tiles** permite acceder a un conjunto personalizado de teselas mediante un URL de la forma _http://{s}.yourtiles.com/{z}/{x}/{y}.png_" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "El siguiente es un ejemplo que utiliza como mapa base el mapa \"World Imagery\" de ESRI. Pueden verse más ejemplos de mapas de ESRI en https://ocefpaf.github.io/python4oceanographers/blog/2015/03/23/wms_layers/." ] }, { "cell_type": "code", "execution_count": 10, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
Make this Notebook Trusted to load map: File -> Trust Notebook
" ], "text/plain": [ "" ] }, "execution_count": 10, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# Mapa \"World Imagery \"de ESRI\n", "m = folium.Map(\n", " location=[10, -84], \n", " width=650, height=400, \n", " zoom_start=7, \n", " tiles='http://services.arcgisonline.com/arcgis/rest/services/World_Imagery/MapServer/MapServer/tile/{z}/{y}/{x}', \n", " attr='ESRI World Imagery')\n", "\n", "m" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Registros de presencia de especies en la [Infraestructura Mundial de Información en Biodiversidad (GBIF)](https://www.gbif.org/). Pueden verse más ejemplos de uso de este tipo de información en la [documentación del API de mapas de GBIF](https://www.gbif.org/developer/maps)." ] }, { "cell_type": "code", "execution_count": 11, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
Make this Notebook Trusted to load map: File -> Trust Notebook
" ], "text/plain": [ "" ] }, "execution_count": 11, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# Registros de presencia de especies en GBIF\n", "m = folium.Map(\n", " location=[0, 0],\n", " width=650, height=400,\n", " zoom_start=1,\n", " tiles='https://api.gbif.org/v2/map/occurrence/density/{z}/{x}/{y}@1x.png?style=purpleYellow.point',\n", " attr='GBIF')\n", "\n", "m" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### Controles" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Folium incorpora también algunos controles para la manipulación del mapa." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "El parámetro **control_scale** es un _booleano_ (cuyo valor por defecto es _False_) que controla la aparición del control de escala en el mapa." ] }, { "cell_type": "code", "execution_count": 12, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
Make this Notebook Trusted to load map: File -> Trust Notebook
" ], "text/plain": [ "" ] }, "execution_count": 12, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# Control de escala\n", "m = folium.Map(\n", " location=[10, -84], \n", " width=650, height=400, \n", " zoom_start=7, \n", " control_scale=True)\n", "\n", "m" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### El método [add_tile_layer()](https://python-visualization.github.io/folium/modules.html#folium.folium.Map.add_tile_layer)\n", "Este método añade una capa de teselas (_tiles_) a un mapa." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "El siguiente ejemplo añade al mapa una capa adicional. Para poder apreciar ambas capas, se adiciona también un control de capas, el cual se explicará en detalle más adelante." ] }, { "cell_type": "code", "execution_count": 13, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
Make this Notebook Trusted to load map: File -> Trust Notebook
" ], "text/plain": [ "" ] }, "execution_count": 13, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# Se crea un mapa\n", "m = folium.Map(\n", " location=[10, -84], \n", " width=650, height=400, \n", " zoom_start=7, \n", " control_scale=True)\n", "\n", "# Se añade una capa base adicional\n", "folium.TileLayer(\n", " tiles='Stamen Terrain', \n", " name='Stamen Terrain').add_to(m)\n", "\n", "# Se crea un control de capas y se añade al mapa mediante el método add_to()\n", "folium.LayerControl().add_to(m)\n", "\n", "m" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### El método [save()](https://python-visualization.github.io/folium/modules.html#folium.folium.Map.save)\n", "Guarda un mapa en un archivo HTML, el cual puede utilizarse en un sitio web. Este método recibe como parámetro el nombre del archivo HTML, como se muestra en el siguiente ejemplo:" ] }, { "cell_type": "code", "execution_count": 14, "metadata": {}, "outputs": [], "source": [ "m.save('index.html')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Clase [LayerControl](https://python-visualization.github.io/folium/modules.html#folium.map.LayerControl)\n", "Crea un control que permite activar y desactivar las capas de un mapa." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "En el siguiente ejemplo, se crea un mapa, se añaden cuatro capas adicionales y también un control de capas para seleccionar cuales capas desean visualizarse." ] }, { "cell_type": "code", "execution_count": 15, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
Make this Notebook Trusted to load map: File -> Trust Notebook
" ], "text/plain": [ "" ] }, "execution_count": 15, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# Creación de un mapa\n", "m = folium.Map(\n", " location=[10, -84], \n", " width=650, height=400, \n", " zoom_start=7, \n", " control_scale=True)\n", "\n", "# Se añaden capas base adicionales\n", "folium.TileLayer(\n", " tiles='CartoDB positron', \n", " name='CartoDB positron').add_to(m)\n", "\n", "folium.TileLayer(\n", " tiles='Stamen Terrain', \n", " name='Stamen Terrain').add_to(m)\n", "\n", "\n", "# ESRI NatGeo World Map\n", "folium.TileLayer(\n", " tiles='http://services.arcgisonline.com/arcgis/rest/services/NatGeo_World_Map/MapServer/MapServer/tile/{z}/{y}/{x}',\n", " name='NatGeo World Map',\n", " attr='ESRI NatGeo World Map').add_to(m)\n", "\n", "# Densidad de registros de presencia de especies\n", "folium.TileLayer(\n", " tiles='https://api.gbif.org/v2/map/occurrence/density/{z}/{x}/{y}@1x.png?&bin=hex&hexPerTile=28&style=classic.poly',\n", " name='Densidad de registros de presencia de especies',\n", " attr='GBIF').add_to(m)\n", "\n", "# Se añade un control de capas\n", "folium.LayerControl().add_to(m)\n", "\n", "m" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Clase [GeoJson](https://python-visualization.github.io/folium/modules.html#folium.features.GeoJson)\n", "Crea un objeto [GeoJson](http://geojson.org/) que puede ser agregado al mapa como una capa." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "En el siguiente ejemplo, se crean dos objetos GeoJson a partir de dos archivos en ese formato, los cuales son añadidos como capas a un mapa. Como puede apreciarse, se utilizan los parámetros **data** y **name** del constructor de la clase **GeoJson** para espeficar los archivos de datos y los nombres de las capas que se desplegarán en el control de capas. El parámetro **show** especifica si la capa se muestra o no desde el inicio. Se emplea también la biblioteca **os** de Python para acceder a funciones del sistema operativo como, en este caso, el acceso a los archivos de datos." ] }, { "cell_type": "code", "execution_count": 16, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
Make this Notebook Trusted to load map: File -> Trust Notebook
" ], "text/plain": [ "" ] }, "execution_count": 16, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# Biblioteca para funciones del sistema operativo\n", "import os\n", "\n", "# Rutas a los archivos GeoJson\n", "cantones_geo = os.path.join('datos/', 'cr_limite_cantonal_ign_wgs84.geojson')\n", "distritos_geo = os.path.join('datos/', 'cr_limite_distrital_ign_wgs84.geojson')\n", "\n", "# Creación del mapa\n", "m = folium.Map(location=[10, -84], tiles='CartoDB positron', zoom_start=7)\n", "\n", "# Se añaden al mapa las capas GeoJson\n", "folium.GeoJson(data=cantones_geo, name='Cantones').add_to(m)\n", "\n", "# Control de capas\n", "folium.LayerControl().add_to(m)\n", "\n", "# Despliegue del mapa\n", "m" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Clase [Marker](https://python-visualization.github.io/folium/modules.html#folium.map.Marker)\n", "Crea un marcador en un punto del mapa con _popup_ emergente y _tooltip_ opcionales." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "El parámetro **location** del constructor de **Marker** se utiliza para especificar la posición del marcador." ] }, { "cell_type": "code", "execution_count": 17, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
Make this Notebook Trusted to load map: File -> Trust Notebook
" ], "text/plain": [ "" ] }, "execution_count": 17, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# Creación del mapa\n", "m = folium.Map(location=[10, -84], tiles='Stamen Toner', zoom_start=7)\n", "\n", "# Se define la posición del marcador y se agrega al mapa con el método add_to()\n", "folium.Marker(location=[10.463333, -84.703333]).add_to(m)\n", "\n", "m" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "El parámetro **popup** se utiliza para especificar una hilera HTML que se desplegará en una ventana emergente al hacer clic sobre el marcador. Por su parte, el parámetro **tooltip** se usa para especificar una hilera de texto que se despliega al colocarse el ratón sobre el marcador." ] }, { "cell_type": "code", "execution_count": 18, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
Make this Notebook Trusted to load map: File -> Trust Notebook
" ], "text/plain": [ "" ] }, "execution_count": 18, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# Creación del mapa\n", "m = folium.Map(location=[10, -84], tiles='Stamen Watercolor', zoom_start=7)\n", "\n", "# Se proporcionan valores para los parámetros \"popup\" y \"tooltip\"\n", "folium.Marker(\n", " location=[10.463333, -84.703333], \n", " popup='Volcan Arenal', \n", " tooltip='Clic para mas informacion').add_to(m)\n", "\n", "m" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Pueden utilizarse los parámetros **color** e **icon** y la clase [Icon](https://python-visualization.github.io/folium/modules.html#folium.map.Icon) para personalizar los íconos de los marcadores. Los íconos pueden obtenerse de galerías como:\n", "- [Font Awesome](https://fontawesome.com/icons?from=io) (debe utilizarse 'fa' como valor del parámetro **prefix**).\n", "- [Glyphicons](https://getbootstrap.com/docs/3.3/components/)\n", "\n", "Para más información, puede consultarse la página [https://github.com/lvoogdt/Leaflet.awesome-markers](https://github.com/lvoogdt/Leaflet.awesome-markers)." ] }, { "cell_type": "code", "execution_count": 19, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
Make this Notebook Trusted to load map: File -> Trust Notebook
" ], "text/plain": [ "" ] }, "execution_count": 19, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# Creación del mapa\n", "m = folium.Map(location=[10.4699398, -84.657898], width=650, height=400, zoom_start=12)\n", "\n", "folium.Marker(\n", " location=[10.463333, -84.703333], \n", " popup='Volcan Arenal', \n", " tooltip='Volcan (clic para más informacion)', \n", " icon=folium.Icon(color='cadetblue', icon='binoculars', prefix='fa')).add_to(m) \n", "\n", "folium.Marker(\n", " location=[10.4697321,-84.6509017], \n", " popup='Hotel Secreto La Fortuna', \n", " tooltip='Hotel (clic para más informacion)', \n", " icon=folium.Icon(color='pink', icon='bed', prefix='fa')).add_to(m)\n", "\n", "folium.Marker(\n", " location=[10.4699015,-84.5823005], \n", " popup='Aeropuerto de La Fortuna', \n", " tooltip='Aeropuerto (clic para mas informacion)', \n", " icon=folium.Icon(color='red', icon='plane', prefix='fa')).add_to(m)\n", "\n", "m" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Clase [CircleMarker](https://python-visualization.github.io/folium/modules.html#folium.vector_layers.CircleMarker)\n", "Crea un marcador con forma de círculo y la medida de su radio como parámetro." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "En el ejemplo que se presenta a continuación, se crean tres marcadores de círculo cuyos radios reflejan el tamaño de la población de las ciudades en los que se ubican." ] }, { "cell_type": "code", "execution_count": 20, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
Make this Notebook Trusted to load map: File -> Trust Notebook
" ], "text/plain": [ "" ] }, "execution_count": 20, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# Creación de un mapa\n", "m = folium.Map(\n", " location=[10, -84], \n", " width=650, \n", " height=400, \n", " zoom_start=7, \n", " control_scale=True)\n", "\n", "# Definición marcadores de círculo\n", "folium.CircleMarker(\n", " location=[9.866667, -83.916667], \n", " popup='Cartago
Poblacion: 156,600 h.', \n", " tooltip='Cartago', \n", " radius=156600/10000).add_to(m)\n", "\n", "folium.CircleMarker(\n", " location=[10.633333, -85.433333], \n", " popup='Liberia
Poblacion: 56,899 h.', \n", " tooltip='Liberia', \n", " radius=56899/10000).add_to(m)\n", "\n", "folium.CircleMarker(\n", " location=[9.983333, -83.033333], \n", " popup='Limón
Población: 58,522 h.', \n", " tooltip='Limón', \n", " radius=58522/10000).add_to(m)\n", "\n", "m" ] } ], "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.9" } }, "nbformat": 4, "nbformat_minor": 2 }