folium

公式サイト

インストール

py -m pip install folium

インポート

import folium

マップの描画

軌跡(Trajectory)のマップを作成した例である。(GPSdata_plotmap/GPSdata_util)

map_index += 1
sw_first = True
# Read CSV File
with open(csv_file, mode='r', encoding='utf-8') as file1:
next(file1) # Skip Header Line
list_csv_file = file1.readlines()
# Plotting
for csv_record in list_csv_file:
list_line = csv_record.replace('"','').replace('\n','').split(',')

if (sw_first == True): # First Record Create folium.Map
# Define Map
folium_figure = folium.Figure() # Default height/width=100%
folium_map.append(folium.Map([list_line[2],list_line[3]],
zoom_start=zoom,control_scale=True).add_to(folium_figure))
sw_first = False

if (list_line[4] == 'Address Not Found'):
display_name = 'Not Found'
else:
display_name = list_line[6]

folium.Marker(location=[list_line[2], list_line[3]],
tooltip=list_line[1],
popup=display_name,
icon=folium.Icon(color="blue")).add_to(folium_map[map_index])

# Display Map (Brawser Dependency)
folium_map[map_index]

# Save HTML File
output_html_file = csv_file.replace('.csv','')+'_folium.html'
folium_map[map_index].save(output_html_file)
  • foliumはplotlyと異なり、DataFrameを入力に使わない。
  • 画面への描画はブラウザーの機能に依存する。できない場合は、保存したHTMLファイルを表示する。

アニメーションマップの描画

foliumでアニメーションを作成した例である。(GPSdata_MobileClip)

厳密なJSON形式の辞書型データを作成する必要がある。

# Set duration by Input Parm
if (map_selection == 'f'): duration = "PT"+str(interval//2)+"S"
else: duration = None

print('\nDataFrame info ---> ')
print(dataframe3.info())

list_unique_uid = pd.unique(dataframe3['uid']).tolist()
print('\nUnique uid Count ---> ', len(list_unique_uid))

dataframe3['datetime'] = \
dataframe3['datetime'].apply(lambda d: pd.Timestamp(d).isoformat(sep='T'))

list_uid = dataframe3['uid'].tolist()
list_lat = dataframe3['lat'].tolist()
list_lng = dataframe3['lng'].tolist()
list_datetime = dataframe3['datetime'].tolist()

#Generate GeoJSON Format
features = [
{
"type": "Feature",
"geometry": {
"type": "MultiPoint",
"coordinates": [[list_lng[i], list_lat[i]]],
},
"properties": {
"times": [datetime],
"popup": "time="+datetime+", uid="+list_uid[i]+", \
lng="+str(list_lng[i])+", lat="+str(list_lat[i]),
"icon": "circle",
"iconstyle": {
#"fillColor": "blue",
"fillColor": folium_colors[
list_unique_uid.index(list_uid[i]) % len(folium_colors)
],
"fillOpacity": opacity,
"stroke": "True",
"radius": weight,
},
},
}
for i, datetime in enumerate(list_datetime, 0)
]

map = folium.Map(
location=[list_lat[0], list_lng[0]],
tiles='OpenStreetMap',
attr='Folium TimestampedGeoJson by ' + os.path.basename(__file__) \
+ ' (Input=' + os.path.basename(input_csv_file) \
+ ', Interval=' + str(interval) + ', Zoom=' + str(zoom) + ')',
control_scale=True,
zoom_start=zoom
)

TimestampedGeoJson(
{
"type": "FeatureCollection",
"features": features,
},
transition_time=200,
loop=False,
auto_play=True,
add_last_point=True,
#period="PT1M",
period="PT"+str(interval)+"S",
#duration="PT1M",
duration=duration,
loop_button=True,
speed_slider=True,
).add_to(map)

#map # Map display does not work.

# Output HTML File (UnicodeEncodeError fixed by asksaveasfilename)
output_html = tkinter.filedialog.asksaveasfilename(
title='Select Output HTML File Name',
initialdir=os.path.dirname(input_csv_file),
initialfile='folium_animation.html',
filetypes=[('HTML','.html')])

map.save(output_html)
  • 同じIDでDurationで指定するタイムフレームに復数のデータがある場合、復数のプロットが同時に(その時刻の表示時に)表れる。
  • そのためGPSdata_MobileClipでは、同じタイムフレームのIDごとに平均値を取って、タイムフレームに1つのプロットが出るようにしている。(平均値は別の関数func_select_between_values()で計算している。)