Skip to main content

Make beautiful maps with Leaflet.js & Python

Project description

Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is furnished to do
so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
Description: .. image:: https://badge.fury.io/py/folium.png
:target: http://badge.fury.io/py/folium
.. image:: https://api.travis-ci.org/python-visualization/folium.png?branch=master
:target: https://travis-ci.org/python-visualization/folium
.. image:: https://badges.gitter.im/Join%20Chat.svg
:target: https://gitter.im/python-visualization/folium?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge
.. image:: https://zenodo.org/badge/18669/python-visualization/folium.svg
:target: https://zenodo.org/badge/latestdoi/18669/python-visualization/folium

Folium
======

|Folium|

Python Data. Leaflet.js Maps.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Folium builds on the data wrangling strengths of the Python ecosystem
and the mapping strengths of the Leaflet.js library. Manipulate your
data in Python, then visualize it in on a Leaflet map via Folium.

Concept
-------

Folium makes it easy to visualize data that's been manipulated in Python
on an interactive Leaflet map. It enables both the binding of data to a
map for choropleth visualizations as well as passing Vincent/Vega
visualizations as markers on the map.

The library has a number of built-in tilesets from OpenStreetMap,
Mapbox, and Stamen, and supports custom tilesets with Mapbox
or Cloudmade API keys. Folium supports both
GeoJSON and TopoJSON overlays, as well as the binding of data to those
overlays to create choropleth maps with color-brewer color schemes.

Installation
------------

.. code:: bash

$ pip install folium

Getting Started
---------------

You can find most of the following examples in the notebook **folium_examples.ipynb** in the examples folder.

To create a base map, simply pass your starting coordinates to Folium:

.. code:: python

import folium
map_osm = folium.Map(location=[45.5236, -122.6750])
map_osm.save('osm.html')

|baseOSM|

| Folium defaults to OpenStreetMap tiles, but Stamen Terrain, Stamen
Toner,
| Mapbox Bright, and Mapbox Control room tiles are built in:

.. code:: python

stamen = folium.Map(location=[45.5236, -122.6750], tiles='Stamen Toner',
zoom_start=13)
stamen.save('stamen_toner.html')

|stamen|

Folium also supports Cloudmade and Mapbox custom tilesets- simply pass
your key to the ``API_key`` keyword:

.. code:: python

custom = folium.Map(location=[45.5236, -122.6750], tiles='Mapbox',
API_key='wrobstory.map-12345678')

Lastly, Folium supports passing any Leaflet.js compatible custom
tileset:

.. code:: python

tileset = r'http://{s}.tiles.yourtiles.com/{z}/{x}/{y}.png'
map = folium.Map(location=[45.372, -121.6972], zoom_start=12,
tiles=tileset, attr='My Data Attribution')

Markers
-------

| Folium supports the plotting of numerous marker types, starting with a
simple Leaflet
| style location marker with popup text:

.. code:: python

map_1 = folium.Map(location=[45.372, -121.6972], zoom_start=12,
tiles='Stamen Terrain')
folium.Marker([45.3288, -121.6625], popup='Mt. Hood Meadows').add_to(map_1)
folium.Marker([45.3311, -121.7113], popup='Timberline Lodge').add_to(map_1)
map_1.save('mthood.html')

|hood|

`Live example <http://bl.ocks.org/wrobstory/5609718>`__

Folium supports colors and marker icon types (from bootstrap)

.. code:: python

map_1 = folium.Map(location=[45.372, -121.6972], zoom_start=12,tiles='Stamen Terrain')
folium.Marker([45.3288, -121.6625], popup='Mt. Hood Meadows',
icon = folium.Icon(icon = 'cloud')).add_to(map_1)
folium.Marker([45.3311, -121.7113], popup='Timberline Lodge',
icon = folium.Icon(color ='green')).add_to(map_1)
folium.Marker([45.3300, -121.6823], popup='Some Other Location',
icon = folium.Icon(color ='red')).add_to(map_1)
map_1.save('iconTest.html')

.. iconTest is broken, TODO: Link to the notebook directly.

Folium also supports circle-style markers, with custom size and color:

.. code:: python

map_2 = folium.Map(location=[45.5236, -122.6750], tiles='Stamen Toner',
zoom_start=13)
folium.Marker(location=[45.5244, -122.6699], popup='The Waterfront').add_to(map_2)
folium.CircleMarker(location=[45.5215, -122.6261], radius=50,
popup='Laurelhurst Park', color='#3186cc',
fill_color='#3186cc').add_to(map_2)
map_2.save('portland.html')

|circle|

`Live example <http://bl.ocks.org/wrobstory/5609747>`__

Folium has a convenience function to enable lat/lng popovers:

.. code:: python

map_3 = folium.Map(location=[46.1991, -122.1889], tiles='Stamen Terrain',
zoom_start=13)
folium.LatLngPopup().add_to(map_3)
map_3.save('sthelens.html')

|latlng|

`Live example <http://bl.ocks.org/wrobstory/5609756>`__

Click-for-marker functionality will allow for on-the-fly placement of
markers:

.. code:: python

map_4 = folium.Map(location=[46.8527, -121.7649], tiles='Stamen Terrain',
zoom_start=13)
folium.Marker(location=[46.8354, -121.7325], popup='Camp Muir').add_to(map_4)
folium.ClickForMarker(popup='Waypoint').add_to(map_4)
map_4.save('mtrainier.html')

|waypoints|

`Live example <http://bl.ocks.org/wrobstory/5609762>`__

Folium also supports the Polygon marker set from the
`Leaflet-DVF <https://github.com/humangeo/leaflet-dvf>`__:

.. code:: python

map_5 = folium.Map(location=[45.5236, -122.6750], zoom_start=13)
folium.RegularPolygonMarker(location=[45.5012, -122.6655], popup='Ross Island Bridge',
fill_color='#132b5e', number_of_sides=3, radius=10).add_to(map_5)
folium.RegularPolygonMarker(location=[45.5132, -122.6708], popup='Hawthorne Bridge',
fill_color='#45647d', number_of_sides=4, radius=10).add_to(map_5)
folium.RegularPolygonMarker(location=[45.5275, -122.6692], popup='Steel Bridge',
fill_color='#769d96', number_of_sides=6, radius=10).add_to(map_5)
folium.RegularPolygonMarker(location=[45.5318, -122.6745], popup='Broadway Bridge',
fill_color='#769d96', number_of_sides=8, radius=10).add_to(map_5)
map_5.save('bridges.html')

|polygon|

`Live example <http://bl.ocks.org/wrobstory/5609786>`__

Vincent/Vega Markers
--------------------

Folium enables passing
`vincent <https://github.com/wrobstory/vincent>`__ visualizations to any
marker type, with the visualization as the popover:

.. code:: python

buoy_map = folium.Map(location=[46.3014, -123.7390], zoom_start=7,
tiles='Stamen Terrain')
popup1 = folium.Popup(max_width=800,
).add_child(folium.Vega(vis1, width=500, height=250))
folium.RegularPolygonMarker([47.3489, -124.708],
fill_color='#43d9de', radius=12, popup=popup1).add_to(buoy_map)
popup2 = folium.Popup(max_width=800,
).add_child(folium.Vega(vis2, width=500, height=250))
folium.RegularPolygonMarker([44.639, -124.5339],
fill_color='#43d9de', radius=12, popup=popup2).add_to(buoy_map)
popup3 = folium.Popup(max_width=800,
).add_child(folium.Vega(vis3, width=500, height=250))
folium.RegularPolygonMarker([46.216, -124.1280],
fill_color='#43d9de', radius=12, popup=popup3).add_to(buoy_map)
buoy_map.save('NOAA_buoys.html')

|vincent|

`Live example <http://bl.ocks.org/wrobstory/5609803>`__

GeoJSON/TopoJSON Overlays
-------------------------

Both GeoJSON and TopoJSON layers can be passed to the map as an overlay,
and multiple layers can be visualized on the same map:

.. code:: python

geo_path = r'data/antarctic_ice_edge.json'
topo_path = r'data/antarctic_ice_shelf_topo.json'

ice_map = folium.Map(location=[-59.1759, -11.6016],
tiles='Mapbox Bright', zoom_start=2)
ice_map.choropleth(geo_path=geo_path)
ice_map.choropleth(geo_path=topo_path, topojson='objects.antarctic_ice_shelf')
ice_map.save('ice_map.html')

|ice|

`Live example <http://bl.ocks.org/wrobstory/5609811>`__

Choropleth Maps
---------------

Folium allows for the binding of 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:

.. code:: python

import folium
import pandas as pd

state_geo = r'data/us-states.json'
state_unemployment = r'data/US_Unemployment_Oct2012.csv'

state_data = pd.read_csv(state_unemployment)

#Let Folium determine the scale
map = folium.Map(location=[48, -102], zoom_start=3)
map.choropleth(geo_path=state_geo, data=state_data,
columns=['State', 'Unemployment'],
key_on='feature.id',
fill_color='YlGn', fill_opacity=0.7, line_opacity=0.2,
legend_name='Unemployment Rate (%)')
map.save('us_states.html')

|states_1|

`Live example <http://bl.ocks.org/wrobstory/5609830>`__

Folium creates the legend on the upper right based on a D3 threshold
scale, and makes the best-guess at values via quantiles. Passing your
own threshold values is simple:

.. code:: python

map.choropleth(geo_path=state_geo, data=state_data,
columns=['State', 'Unemployment'],
threshold_scale=[5, 6, 7, 8, 9, 10],
key_on='feature.id',
fill_color='BuPu', fill_opacity=0.7, line_opacity=0.5,
legend_name='Unemployment Rate (%)',
reset=True)
map.save('us_states.html')

|states_2|

`Live example <http://bl.ocks.org/wrobstory/5609856>`__

By binding data via the Pandas DataFrame, different datasets can be
quickly visualized. In the following example, the ``df`` DataFrame
contains six columns with different economic data, a few of which we
will visualize:

.. code:: python

#Number of employed with auto scale
map_1 = folium.Map(location=[48, -102], zoom_start=3)
map_1.choropleth(geo_path=county_geo, data_out='data1.json', data=df,
columns=['GEO_ID', 'Employed_2011'],
key_on='feature.id',
fill_color='YlOrRd', fill_opacity=0.7, line_opacity=0.3,
topojson='objects.us_counties_20m')
map_1.save('map_1.html')

|counties_1|

`Live example <http://bl.ocks.org/wrobstory/5609889>`__

.. code:: python

#Unemployment with custom defined scale
map_2 = folium.Map(location=[40, -99], zoom_start=4)
map_2.choropleth(geo_path=county_geo, data_out='data2.json', data=df,
columns=['GEO_ID', 'Unemployment_rate_2011'],
key_on='feature.id',
threshold_scale=[0, 5, 7, 9, 11, 13],
fill_color='YlGnBu', line_opacity=0.3,
legend_name='Unemployment Rate 2011 (%)',
topojson='objects.us_counties_20m')
map_2.save('map_2.html')

|counties_2|

`Live example <http://bl.ocks.org/wrobstory/5609934>`__

.. code:: python

#Median Household income
map_3 = folium.Map(location=[40, -99], zoom_start=4)
map_3.choropleth(geo_path=county_geo, data_out='data3.json', data=df,
columns=['GEO_ID', 'Median_Household_Income_2011'],
key_on='feature.id',
fill_color='PuRd', line_opacity=0.3,
legend_name='Median Household Income 2011 ($)',
topojson='objects.us_counties_20m')
map_3.save('map_3.html')

|counties_3|

`Live example <http://bl.ocks.org/wrobstory/5609959>`__

Dependencies
------------

Jinja2

Pandas (Map Data Binding only)

Numpy (Map Data Binding only)

Vincent (Map Data Binding only)

Status
------

Beta

Docs
----

https://folium.readthedocs.org/

.. |Folium| image:: http://farm3.staticflickr.com/2860/8754661081_c40e5a214c_o.jpg
.. |baseOSM| image:: http://farm6.staticflickr.com/5334/8754817259_de071db265_c.jpg
.. |stamen| image:: http://farm3.staticflickr.com/2883/8755937912_1d9ef78118_c.jpg
.. |hood| image:: http://farm4.staticflickr.com/3666/8755937936_d7efbc6dee_c.jpg
.. |iconTest| image:: http://cl.ly/image/2b0l1K0v370P/icon_test.png
.. |circle| image:: http://farm9.staticflickr.com/8280/8755938394_9f491ef79f_c.jpg
.. |latlng| image:: http://farm4.staticflickr.com/3698/8755938152_14bc024bde_c.jpg
.. |waypoints| image:: http://farm6.staticflickr.com/5343/8754817433_2ecde65790_c.jpg
.. |polygon| image:: http://farm8.staticflickr.com/7405/8754817131_24285bff5f_c.jpg
.. |vincent| image:: http://farm4.staticflickr.com/3699/8754817119_4a14ebc3fe_c.jpg
.. |ice| image:: http://farm8.staticflickr.com/7335/8754817253_f32155f902_c.jpg
.. |states_1| image:: http://farm3.staticflickr.com/2837/8755937872_ed5ec8e854_c.jpg
.. |states_2| image:: http://farm9.staticflickr.com/8542/8754816951_752b8a7867_c.jpg
.. |counties_1| image:: http://farm4.staticflickr.com/3792/8755938318_bc82a81c64_c.jpg
.. |counties_2| image:: http://farm9.staticflickr.com/8140/8754817355_2bfea43ff5_c.jpg
.. |counties_3| image:: http://farm4.staticflickr.com/3755/8755938218_06fdc51d40_c.jpg

0.3.0
~~~~~

- Switched to `leaflet 1.0.1` (juoceano #531 and ocefpaf #535)
- Added `continuous_world`, `world_copy_jump`, and `no_wrap` options (ocefpaf #508)
- Update font-awesome to 4.6.3 (ocefpaf #478)
- Added text path (talespaiva #451 and ocefpaf #474)
- More options added to `LayerControl` (qingkaikong #473)
- More options added to `fullscreen` plugin (qingkaikong #468)
- Added `ColorLine` object (bibmartin #449)
- Added highlight function to `GeoJSON`, and `Chrorpleth` (JoshuaCano #341)
- Added `fullscreen` plugin (sanga #437)
- Added `smooth_factor `option to `GeoJSON`, `TopoJSON` and `Choropleth` (JamesGardiner #428)
- `Map` object now accepts Leaflet global switches (sgvandijk #424)
- Added weight option to CircleMarker (palewire #581)

Bug Fixes

- Fixed image order (juoceano #536)
- Fixed Icon rotation (juoceano #530 and sseemayer #527)
- Fixed MIME type (text/plain) is not executable (talespaiva #440)
- Update Travis-CI testing to incorporate branca and fix notebook tests (ocefpaf #436)
- Removed MultiPolyLine and MultiPolygon, both are handled by PolyLine and PolyLine in leaflet 1.0.* (ocefpaf #554)
- Removed deprecated MapQuest tiles (HashCode55 #562)

0.2.1
~~~~~
Bugfix release

- TopoJson.get_bounds() returns [lon,lat] instead of [lat,lon] (eddies #383)
- HeatMap was not passing "name" argument (eddies #380)
- Fix heatmap.fit_bounds (same bug as #383) (BibMartin #384)
- Fix WMS rendering (ocefpaf #404)
- Change Leaflet.awesome-markers URL (BibMartin #393)

0.2.0
~~~~~
Major changes to the API with the new plugin system,
and several new features in this version. For more information check the docs:
http://python-visualization.github.io/folium/

- Added control_scale (BibMartin and jelmelk #355)
- WMS styles (ocefpaf #348)
- Docs! (BibMartin #344, #337, #329)
- No tile option (ocefpaf #330)
- GeoJSON and TopoJSON `style_function` (BibMartin #317 and #266)
- Colormaps (BibMartin # 300)
- Map CRS (BibMartin #297)
- GeoPandas drawing (BibMartin #296)
- Div Icons (BibMartin #250)
- CustomIcon (BibMartin #230)
- HeatMap (BibMartin #213)

And many bug fixes.
See https://github.com/python-visualization/folium/issues?&q=milestone:v0.2.0+is:closed+label:bug

0.1.6
~~~~~
- Added Image Overlay. (andrewgiessel b625613)
- All popups can take a `popup_width` keyword to adjust the width in
text/HTML (ocefpaf #157).
- CAVEAT! Backwards incompatibly change: the keyword `width` in popups is now
`popup_width` to avoid confusion with map `width`.


0.1.5
~~~~~
- Popups on lines. (themiurgo #122)
- Map auto bounds. (themiurgo #134)
- GeoJSON popup. (ocefpaf 7aad5e0)
- Added cartodb positron and dark_matter tiles (ocefpaf d4daee7)
- Forcing HTTPS when available. (ocefpaf c69ac89)
- Added Stamen Watercolor tiles. (ocefpaf 8c1f837)
- Added non-pixel width and height. (ocefpaf a87a449)
- Default map size is defined as non-pixel and equal to 100% of the window.
(ocefpaf dcaf575)

Bug Fixes

- Draw GeoJSON first. (ocefpaf d92bdbe)
- Removed keyword unnecessary `popup_on`. (themiurgo 204d722)
- Fixed MapQuest Open Aerial URL. (ocefpaf 5e787fa)


0.1.4
~~~~~
- Popups allow unicode. (Anand Patil 545315a)
- Loading javascript over https. (Anand Patil ac9a4d6)
- Added `width` keyword to simple_popup. (ocefpaf 95325c4)
- Support multi_polyline. (Younggun Kim efbd1db)
- Added max and min zoom keywords. (ocefpaf 4ca4c92)

Bug Fixes

- Remove margins from leaflet-tiles. (Lennart Fricke 3c11433)
- Fix #50 template not found on Windows OSes. (ocefpaf 101daee)
- Fixed `add_wms_layer` py3k bug. (ocefpaf 154f0a5)


0.1.3
~~~~~
- Bootstrap glyphicon marker icons. @birdage
- Cluster marker group, and simple markers . (birdage 801d91c)
- WMS tile. (birdage 26f9668)
- Expanded color support to 253 with colorbrewer. (Adam Pah 3ba39ae)
- Port to python 3. (Pavel Tysliatski 5093e1b)
- Update geojson_template to Leaflet.js 0.7. (Justin Duke a917551)
- Update fol_template to Leaflet.js 0.7. (Justin Duke b328cec)
- Add support for lines. (Jacob Wasserman e3be077)
- Allow rendering w/ custom template. (Samat K Jain 1a85841)
- MapQuest Open tilesets. (Samat K Jain d536949)

Bug Fixes

- Vincent popups take padding into account. (Kyle Corbitt 26556fe)
- Simple popups correctly escape internal quotes. (Kyle Corbitt 20c979f)
- Add encoding specification. @jmduke
- Reverted change to mathchColor. (Roy Keyes 70d7f5c)
- Changed no-data fill to null/no-fill, rather than #fff. (Rob Story 6ff80a6)
- Fixed issue with counties TopoJSON. (Rob Story cddaab3)


0.1.2
~~~~~
- TopoJSON functionality. (Rob Story 5566b71)
- Vincent/Vega charts as popups. (Rob Story 4b7e402)
- GeoJSON overlays added. (Rob Story b5d9081)
- Click to add markers, popover Lat/Lng functionality. (Rob Story 9c809f9)
- Simple and Circle markers added. (Rob Story 181ac51)
- Initial commit. (Rob Story 6a43874)

Keywords: data visualization
Platform: UNKNOWN
Classifier: Programming Language :: Python :: 2.7
Classifier: Programming Language :: Python :: 3.3
Classifier: Programming Language :: Python :: 3.4
Classifier: Programming Language :: Python :: 3.5
Classifier: Topic :: Scientific/Engineering :: GIS
Classifier: Topic :: Scientific/Engineering :: Visualization
Classifier: License :: OSI Approved :: MIT License
Classifier: Development Status :: 5 - Production/Stable

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

folium-0.3.0.tar.gz (735.1 kB view hashes)

Uploaded source

Built Distributions

folium-0.3.0-py3-none-any.whl (71.7 kB view hashes)

Uploaded py3

folium-0.3.0-py2-none-any.whl (71.7 kB view hashes)

Uploaded py2

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page