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()で計算している。)

plotly

公式サイト

インストール

py -m pip install plotly==5.24.1 
  • バージョンを指定しなければ、最新版がインストールされる。

インポート

import plotly.express as px
  • インストールは”plotly”で行い、インポートは”plotly.express”にする。

マップの描画

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

zoom = 16.0    # Default Zoom Value
csv_file = 'currently processing csv file name'

# Read CSV File in DataFrame
df1 =pd.read_csv(csv_file)
df1.dropna(inplace=True, how='all')

fig = px.scatter_mapbox(
data_frame=df1,
lat="Lat",
lon="Lng",
hover_data=["DateTime","display_name"],
color="category",
size="StayTime",
size_max=100,
opacity=0.5,
zoom=zoom,
height=None,
width=None,
title='plotly Map of'+csv_file)
fig.update_layout(mapbox_style='open-street-map')
fig.update_layout(margin={"r": 0, "t": 0, "l": 0, "b": 0})
fig.update_layout(autosize=True)
fig.show()

# Output HTML File
output_html_file = csv_file.replace('.csv','')+'_plotly.html'
fig.write_html(output_html_file)
  • 実際の使用方法は様々なので、ドキュメントを参照する必要がある。
  • plotlyはDataFrameから直接書き出すことができる。

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

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

print('\nStart func_mapplot_plotly()')

# dataframe1.dropna(inplace=True, how='all')

fig = px.scatter_mapbox(
data_frame=dataframe3,
animation_frame="datetime",
animation_group="uid",
lat="lat",
lon="lng",
hover_name="uid",
color="uid",
size="lat",
size_max=20,
opacity=opacity,
zoom=zoom,
height=None,
width=None,
title='Plotly Animation by ' + os.path.basename(__file__) \
+ ' (Input=' + os.path.basename(input_csv_file) \
+ ', Interval=' + str(interval) + ', Zoom=' + str(zoom) + ')'
)
fig.update_layout(mapbox_style='open-street-map')
fig.update_layout(margin={"r": 0, "t": 24, "l": 0, "b": 0})
fig.update_layout(autosize=True)
fig.show()

# 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='plotly_animation.html',
filetypes=[('HTML','.html')])

fig.write_html(output_html)

print('End func_mapplot_plotly()')
  • DataFrameから直接描画することができる。
  • 右上に凡例が表示され、IDごとにメモリーエリアが確保されるようである。そのためIDごとのデータが時間的に継続していない場合、表示がおかしくなる。
    • Current Animation Limitations and Caveats
      • Animations are designed to work well when each row of input is present across all animation frames, and when categorical values mapped to symbol, color and facet are constant across frames. Animations may be misleading or inconsistent if these constraints are not met.

import

ドキュメント

Importステートメント

絶対importの例(推奨)
import sound.effects.echo
import sound.effects.surround
from sound.effects import *
相対importの例(非推奨)
from . import echo        ←Current Packageからimport
from .. import formats      ←Parent Packageからimport
from ..filters import equalizer  ←Parent Packageのfiltersからimport

ソースファイルをimportして即実行

Mainプログラムにimportしたら、importされたプログラムが即実行される。

Main Program
#Main Routine
print('Importings!')

import temp02 ←この時点で実行

print('terminated')
Sub Program
import tkinter.filedialog

input_file = tkinter.filedialog.askopenfilename(
title='Select Input File Name',
initialdir='c:/Users/m/Downloads',
filetypes=[('All','*')])

print('Inoput file is ---> ', input_file)
  • ただし、1回目はimportステートメントで実行されるが、2回目移行はimportがキャッシュされていて実行されない。2回目以降も実行するには、呼び出されるプログラムを関数化しなければならない。
  • importしたソース内のFunctionは、importした後に呼び出す必要がある。

Nuitka

(Nuitkaは、アプリケーションにインポートするモジュールではないので、モジュールカテゴリーではなく単独のカテゴリーに分類した。)

インストール

モジュールのインストールは、通常のモジュールと同様にpipで行う。モジュールのインストールを参照する。

実行

Nuitkaを使って、Pythonソースコードから.exe化する方法は以下の通り。

  1. コマンドプロンプトを起動する。
  2. ソースコードと出力が書き出されるフォルダに移動する。
  3. 以下のコマンドを実行する。
py -m nuitka --onefile --enable-plugin=tk-inter Source.py
  • オプションのダブルハイフンは、コピーペーストでシングルハイフンに変わってしまうことがあるので、ダブルハイフンになっていることを確認する。
  • Cコンパイルが必要なモジュール(例えばtkinter)をインポートしている場合は、別途そのモジュールのコンパイルが必要なので、”–enable-plugin=“を追加する必要がある。
    • 忘れると.exe化した実行モジュール実行時に、エラーメッセージでこのコマンドを入れてNuitkaを実行し直すように促される。
  • Nuitkaによって2つのフォルダが生成されるが、.exeファイル以外は削除してよい。