Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
python-visualization
GitHub Repository: python-visualization/folium
Path: blob/main/tests/plugins/test_time_slider_choropleth.py
1601 views
1
"""
2
tests TimeSliderChoropleth
3
--------------------------
4
5
"""
6
7
import json
8
import sys
9
10
import numpy as np
11
import pandas as pd
12
import pytest
13
from branca.colormap import linear
14
15
import folium
16
from folium.plugins import TimeSliderChoropleth
17
from folium.utilities import normalize
18
19
20
@pytest.mark.xfail(sys.version_info[0:2] == (3, 8), reason="too modern for py38")
21
def test_timedynamic_geo_json():
22
"""
23
tests folium.plugins.TimeSliderChoropleth
24
"""
25
import geodatasets
26
import geopandas as gpd
27
28
datapath = geodatasets.get_path("naturalearth land")
29
gdf = gpd.read_file(datapath)
30
31
"""
32
Timestamps, start date is carefully chosen to be earlier than 2001-09-09
33
(9 digit timestamp), end date is later (10 digits). This is to ensure an
34
integer sort is used (and not a string sort were '2' > '10').
35
datetime.strftime('%s') on Windows just generates date and not timestamp so avoid.
36
"""
37
n_periods = 3
38
dt_range = pd.Series(pd.date_range("2001-08-1", periods=n_periods, freq="ME"))
39
dt_index = [f"{dt.timestamp():.0f}" for dt in dt_range]
40
41
styledata = {}
42
43
for country in gdf.index:
44
pdf = pd.DataFrame(
45
{
46
"color": np.random.normal(size=n_periods),
47
"opacity": np.random.normal(size=n_periods),
48
},
49
index=dt_index,
50
)
51
styledata[country] = pdf.cumsum()
52
53
max_color, min_color = 0, 0
54
55
for country, data in styledata.items():
56
max_color = max(max_color, data["color"].max())
57
min_color = min(max_color, data["color"].min())
58
59
cmap = linear.PuRd_09.scale(min_color, max_color)
60
61
# Define function to normalize column into range [0,1]
62
def norm(col):
63
return (col - col.min()) / (col.max() - col.min())
64
65
for country, data in styledata.items():
66
data["color"] = data["color"].apply(cmap)
67
data["opacity"] = norm(data["opacity"])
68
69
styledict = {
70
str(country): data.to_dict(orient="index")
71
for country, data in styledata.items()
72
}
73
74
m = folium.Map((0, 0), zoom_start=2)
75
76
time_slider_choropleth = TimeSliderChoropleth(gdf.to_json(), styledict)
77
time_slider_choropleth.add_to(m)
78
79
rendered = time_slider_choropleth._template.module.script(time_slider_choropleth)
80
81
m._repr_html_()
82
out = normalize(m._parent.render())
83
assert '<script src="https://d3js.org/d3.v4.min.js"></script>' in out
84
85
# We verify that data has been inserted correctly
86
expected_timestamps = sorted(dt_index, key=int) # numeric sort
87
expected_timestamps = f"let timestamps = {expected_timestamps};"
88
expected_timestamps = expected_timestamps.split(";")[0].strip().replace("'", '"')
89
rendered_timestamps = rendered.strip(" \n{").split(";")[0].strip()
90
assert expected_timestamps == rendered_timestamps
91
92
expected_styledict = normalize(json.dumps(styledict, sort_keys=True))
93
assert expected_styledict in normalize(rendered)
94
95