Jovian
Sign In
Learn practical skills, build real-world projects, and advance your career

An Introductory Guide to Folium

Folium

Folium is a powerful Python library that allows us to manipulate geospatial data and visualize it on a leaflet map making our visualizations interactive.
Note: Leaflet is a leading open-source JavaScript library for plotting interactive maps.

This way, Folium has the flexibility of python and the strength of leaflet.js library. This quality makes Folium easy to use and efficient to create dashboards.

alt

Installing and Importing Folium

Folium is pre installed on Google Colab as well Kaggle, but you can use the following pip command to install folium locally.

!pip install folium --quiet

import folium 

Latitude and Longitude

Folium accepts geographical coordinates in the form [[ latitude, longitude ]] which become the pivots of our maps.

Latitude and Longitudes are angles that uniquely define the points in a sphere.
alt

A LATITUDE ranges from 0°90°0°-90° top and bottom. We ususally follow the Gemoetric Sign convention i.e +ve+ve above 0° and ve-ve below 0°.

Simillarly, a LONGITUDE ranges from 0°180°0°-180° left and right. Again, we follow the Gemoetric Sign convention i.e +ve+ ve from 0° to 180°180° right, and ve-ve from 0° to 180°180° left.

alt

FunFact: The Null Island

alt

Imgur

Creating your first interactive Map

To create a basic interractive map, folium provides a simple method called folium.Map which takes the coordinates of our base location in the location argument.

Additionally, we can set the zoom level using the argument zoom_start. Higher the value inserted in zoom_start, higher the zoom in level. Below, I have created a simple map with the location coordinates of San Jose, Costa Rica.

map = folium.Map(location=[9.9281, -84.0907], zoom_start=13)
map

Saving a Folium Map

By default, folium creates a map in seperate HTML file. We can save them using .save. This allows us to view our map on an HTML page.

map.save("SanJose.html")

Tile Styles in Folium

Folium offers different styles to generate our maps. Each style is a different tileset made up of vector data.

A vector tile is a lightweight data format for storing geospatial vector data, such as points, lines, and polygons.

The following tilesets are available with Folium:

  • OpenStreetMap
  • Mapbox Bright
  • Mapbox Control Room
  • Stamen (incl. Terrain, Toner, and Watercolor)
  • Cloudmade
  • Mapbox
  • CartoDB (incl. positron and dark_matter)

Each of these styles showcase different features of a map hence can be used for different purposes.

In case no tiles is specified, folium provides the OpenStreetMap view by default.

Below we have plotted a Topographic map of San Jose and other parts of Costa Rica using Stamen Terrain. This shows large-scale detail and quantitative representation of relief features with the help of contour lines etc.

map = folium.Map(location=[9.9281, -84.0907], zoom_start=10, tiles='Stamen Terrain')
map

Because each tileset is a different layer and provides different information, we can add each layer to the same map using the .add_to function.

Cuboid layers image

map = folium.Map(location=[9.9281, -84.0907], zoom_start=10, tiles='Stamen Terrain')

folium.TileLayer('Stamen Terrain').add_to(map)
folium.TileLayer('Stamen Toner').add_to(map)
folium.TileLayer('Stamen Water Color').add_to(map)
folium.TileLayer('cartodbpositron').add_to(map)
folium.TileLayer('cartodbdark_matter').add_to(map)

folium.LayerControl().add_to(map)
map

You can control or change the map tile from the top right corner of your map.

Adding Markers to your Folium Maps

From the oldest map ever drawn, Markers have been an essential part of cartography. These help to indicate the type of destination or the destination itself.

Folium allows us to create markers in two simple steps:

  • First we use the folium.Marker() class to declare a marker. We can also add arguments popup and tootip to control what we see when hovering over them.

  • Next we can simply add these markers to our base map using the function .add_child(map).

map = folium.Map(location=[9.9281, -84.0907], zoom_start=9)

folium.Marker(
    [10.204899282955244, -84.16153139999999],
     popup="<i>La Paz Waterfall Gardens Nature Park, Costa Rica</i>").add_to(map)
folium.Marker(
    [10.441940811102523, -84.66740968917554],
     popup="<b>La Fortuna Waterfall, Costa Rica</b>").add_to(map)

map

The difference between tooltip and popup is that the content visible over a marker when we hover over it is called TOOLTIP, whereas the content visible over a marker when we click it is called POPUP.

Changing Marker Icons and colors

Folium offers ways to mark your map with markers of variable icons and colors to indicate different localities.

MArker image

You can find the full list of icons and color's supported by folium here: https://getbootstrap.com/docs/3.3/components/

map = folium.Map(location=[9.9281, -84.0907], tiles='Stamen Terrain', zoom_start=10)

folium.Marker(
    [10.204899282955244, -84.16153139999999],
     popup="<i>La Paz Waterfall Gardens Nature Park, Costa Rica</i>",
     icon=folium.Icon(color='green',icon="glyphicon glyphicon-tree-deciduous" ) 
     ).add_to(map)
folium.Marker(
    [10.441940811102523, -84.66740968917554],
     popup="<b>La Fortuna Waterfall, Alajuela Province, La Fortuna, Costa Rica</b>",
     icon=folium.Icon(color='green',icon="glyphicon glyphicon-tree-deciduous" ) 
     ).add_to(map)

map

Adding Explicit Markers While Interacting

Another feature within folium is that we can explicitly add a marker to our map. It can be done using a simple function ClickForMarker(), and .add_child().

Let's look at it below. You should be able to drop markers with a simple click.

from folium.map import Icon
map = folium.Map(location=[9.9281, -84.0907], zoom_start=9)

folium.Marker(
    [10.204899282955244, -84.16153139999999],
     popup="<i>La Paz Waterfall Gardens Nature Park, Costa Rica</i>",
     icon=folium.Icon(color='green')
     ).add_to(map)
folium.Marker(
    [10.441940811102523, -84.66740968917554],
     popup="<b>La Fortuna Waterfall, Alajuela Province, La Fortuna, Costa Rica</b>",
     icon=folium.Icon(color='green')).add_to(map)

map.add_child(folium.ClickForMarker(popup="NewMarker"))
map

Drawing Shapes

Another feature to make your map results more precise are highlighting an area with the help of shapes. Below is an example where I've used folium.Circle, added arguments like radius, color, etc... & added it to my base map.

map = folium.Map(location=[9.9281, -84.0907], zoom_start=10)

folium.Circle(
    radius=500,
    location = [10.202164194235301, -84.23876102272602],
    popup = "Poás Volcano",
    color = 'red',
    fill = True
).add_to(map)

folium.CircleMarker(
    location=[9.9281, -84.0907],
    radius = 50,
    popup = 'SanJose',
    color = "green",
    fill = False
).add_to(map)

map

The size of your marker remains intact even if your zoom in or out on your map. You can explore a whole other bunch of different shapes you can highlight on a map.

GeoJSON and TopoJSON Overlays

A point on a map mostly consists of latitude and longitude, but sometimes you can add other physical factors on a map like a path or a boundary. For this we use GeoJSON & TopoJSON formats.

GeoJSON is an open standard format for encoding a variety of geographic data structures.
This helps to represent different geospatial features using JSON.

{
  "type": "Feature",
  "geometry": {
    "type": "Point",
    "coordinates": [125.6, 10.1]
  },
  "properties": {
    "name": "Dinagat Islands"
  }
}

TopoJSON on the side is an extension of GeoJSON files that encodes the Topology of a certain space. This format contains both geospatial data (arcs) and attribute data.

We can pass GeoJSON and TopoJSON layers as an overlay, and multiple layers can be visualized on the map. To plot a map with GeoJSON and TopoJSON data structures Folium has two methods:

  • folium.GeoJson &
  • folium.TopoJson.

Let's implement them.

Dataset: Since there was not a lot of data representing Indian states online, I've used local data. I've uploaded the dataset on kaggle: https://www.kaggle.com/datasets/himanigulati/topo-choro-json-files. You can download it and manually upload it to your jupyter notebook.

import json

f = open('/content/IndiaStates_topo.json')
india_dist = json.load(f)

v = open('/content/IndiaStates_topo.json')
india_states_topo = json.load(v)
--------------------------------------------------------------------------- FileNotFoundError Traceback (most recent call last) /tmp/ipykernel_39/3209328809.py in <module> 1 import json 2 ----> 3 f = open('/content/IndiaStates_topo.json') 4 india_dist = json.load(f) 5 FileNotFoundError: [Errno 2] No such file or directory: '/content/IndiaStates_topo.json'
map = folium.Map(location=[22, 78],
                 zoom_start=4,
                 tiles = 'cartodbpositron')

#folium.GeoJson(india_dist, name="geojson").add_to(map)

folium.TopoJson(india_states_topo, 'objects.India_States_2020_compressed', name="topojson").add_to(map)
                
map
--------------------------------------------------------------------------- NameError Traceback (most recent call last) /tmp/ipykernel_39/2846193947.py in <module> 5 #folium.GeoJson(india_dist, name="geojson").add_to(map) 6 ----> 7 folium.TopoJson(india_states_topo, 'objects.India_States_2020_compressed', name="topojson").add_to(map) 8 9 map NameError: name 'india_states_topo' is not defined
Additional Map for River Centerlines:

Follwing GeoJSON Data represents, Rivers and Lakes Centerlines on a map made around the null point. You can find the data here: https://d2ad6b4ur7yvpq.cloudfront.net/

river_url = "https://d2ad6b4ur7yvpq.cloudfront.net/naturalearth-3.3.0/ne_50m_rivers_lake_centerlines.geojson"

map = folium.Map(location=[0, 0], tiles='Stamen Watercolor', zoom_start=2)

folium.GeoJson(river_url, name="geojson").add_to(map)

map

Dataset: For the topo JSON overlay example

json.load()
import json

CHOROPLETH and HEATMAPS with FOLIUM:

A choropleth map is a type of statistical thematic map that uses varying intensity of color to aggregate a concrete summary of a geographic characteristic. For Example: population desity, unemployment rate.

To create a Choropleth map, we need a GeoJSon file that represents what we want to plot.

Let's create a

climate_url = ('https://raw.githubusercontent.com/michaelx/climate/master/climate.json')

import pandas as pd

climate_data = pd.read_json(climate_url)

map = folium.Map(location=[0,0], zoom_start=2, tiles = 'cartodbpositron')

map
 
 

Conclusion

!pip install opendatasets --upgrade --quiet
import opendatasets as od
dataset_url ="https://www.kaggle.com/datasets/daveianhickey/2000-16-traffic-flow-england-scotland-wales"
od.download(dataset_url)
Please provide your Kaggle credentials to download this dataset. Learn more: http://bit.ly/kaggle-creds Your Kaggle username: himanigulati Your Kaggle Key: ········ Downloading 2000-16-traffic-flow-england-scotland-wales.zip to ./2000-16-traffic-flow-england-scotland-wales
100%|██████████| 132M/132M [00:02<00:00, 48.1MB/s]
df_acc = pd.read_csv()
 
 
 
 
 
 
# Execute this to save new versions of the notebook
jovian.commit(project="folium-introduction")
[jovian] Detected Colab notebook... [jovian] Please enter your API key ( from https://jovian.ai/ ): API KEY: ··········
[jovian] Error: The current API key is invalid or expired.
[jovian] Please enter your API key ( from https://jovian.ai/ ): API KEY:
himani007
Himani10 months ago