Skip to content

Commit 18c0069

Browse files
author
Martin Journois
committed
Create HeatMap as suggested in #213
1 parent 57f2e37 commit 18c0069

File tree

3 files changed

+86
-0
lines changed

3 files changed

+86
-0
lines changed

folium/plugins/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,3 +10,4 @@
1010
from .terminator import Terminator
1111
from .boat_marker import BoatMarker
1212
from .timestamped_geo_json import TimestampedGeoJson
13+
from .heat_map import HeatMap

folium/plugins/heat_map.py

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
# -*- coding: utf-8 -*-
2+
"""
3+
Heat map
4+
--------
5+
6+
Create a HeatMap layer
7+
"""
8+
import json
9+
from jinja2 import Template
10+
11+
from folium.element import JavascriptLink, Figure
12+
from folium.map import TileLayer
13+
14+
class HeatMap(TileLayer):
15+
def __init__(self, data, name=None,
16+
min_opacity = .5, max_zoom=18, max_val=1.,
17+
radius=25, blur=15, gradient=None,
18+
overlay = True):
19+
"""Create a Heatmap layer
20+
21+
Parameters
22+
----------
23+
data : list of points of the form [lat, lng, weight]
24+
The point you want to plot.
25+
name : str
26+
The name of the layer that will be created.
27+
min_opacity : default 1.
28+
The minimum opacity the heat will start at.
29+
max_zoom : default 18
30+
Zoom level where the points reach maximum intensity (as intensity scales with zoom),
31+
equals maxZoom of the map by default
32+
max_val : float, default 1.
33+
Maximum point intensity
34+
radius : int, default 25
35+
Radius of each "point" of the heatmap
36+
blur : int, default 15
37+
Amount of blur
38+
gradient : dict, default None
39+
Color gradient config. e.g. {0.4: 'blue', 0.65: 'lime', 1: 'red'}
40+
"""
41+
super(TileLayer, self).__init__()
42+
self._name = 'HeatMap'
43+
self.tile_name = name if name is not None else self.get_name()
44+
45+
self.data= data
46+
self.min_opacity = min_opacity
47+
self.max_zoom = max_zoom
48+
self.max_val = max_val
49+
self.radius = radius
50+
self.blur = blur
51+
self.gradient = json.dumps(gradient, sort_keys=True) if gradient is not None else "null"
52+
self.overlay = overlay
53+
54+
self._template = Template(u"""
55+
{% macro script(this, kwargs) %}
56+
var {{this.get_name()}} = L.heatLayer(
57+
{{this.data}},
58+
{
59+
minOpacity: {{this.min_opacity}},
60+
maxZoom: {{this.max_zoom}},
61+
max: {{this.max_val}},
62+
radius: {{this.radius}},
63+
blur: {{this.blur}},
64+
gradient: {{this.gradient}}
65+
})
66+
.addTo({{this._parent.get_name()}});
67+
{% endmacro %}
68+
""")
69+
70+
def render(self, **kwargs):
71+
super(TileLayer, self).render()
72+
73+
figure = self.get_root()
74+
assert isinstance(figure,Figure), ("You cannot render this Element "
75+
"if it's not in a Figure.")
76+
77+
figure.header.add_children(\
78+
JavascriptLink("https://leaflet.github.io/Leaflet.heat/dist/leaflet-heat.js"),
79+
name='leaflet-heat.js')

tests/test_plugins.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,3 +134,9 @@ def test_timestamped_geo_json(self):
134134
mape = folium.Map([47, 3], zoom_start=1)
135135
mape.add_children(plugins.TimestampedGeoJson(data))
136136
mape._repr_html_()
137+
138+
def test_heat_map(self):
139+
data = (np.random.normal(size=(100,2))*np.array([[1,1]])+np.array([[48,5]])).tolist()
140+
mapa = folium.Map([48., 5.], tiles='stamentoner', zoom_start=6)
141+
mapa.add_children(plugins.HeatMap(data))
142+
mapa._repr_html_()

0 commit comments

Comments
 (0)