データは、研究室サーバ 8tops.yamanashi.ac.jp上にある。データの形式はGoogle Driveの2019年フォルダにある「Wi-Fiデータ処理・形式」というメモを参照のこと。
# 流動プロット用関数定義
# データはデータベースに格納されている
# DB接続
import sqlite3
import pandas as pd
import matplotlib.pyplot as plt
font_size =24
fig_size = (14,8)
# 8tops上でのファイル (ファイル名は環境に応じて変更すること)
conn = sqlite3.connect("/home/raspimngr/db/kofu_traveler.sqlite3")
#conn = sqlite3.connect("kofu_traveler.sqlite3")
cur = conn.cursor()
# テーブル名 (flow, flow_trunc10, flow_all_trunc, flow_all, flow_all_trunc10のどれか)
table_name = "flow_all_trunc10"
# 時間帯別流動数
def plot_hourly_flow(path, sub_title="", filename_body="temp", image_type="", direction=False,
sdate="2019-09-01", edate="2019-12-31", legend_outside=False):
count_data = {"00": {}, "01":{},"02": {},"03": {},"04": {},"05": {},"06": {},"07": {},"08": {},"09": {},
"10": {},"11": {},"12": {},"13": {},"14": {},"15": {},"16": {},"17": {},"18": {},"19": {},
"20": {},"21": {},"22": {},"23": {}}
opt_direction = ""
for l, pos in path.items():
if direction:
opt_direction = ''
else:
opt_direction = ' or (origin="' + pos[1] + '" and destination="' + pos[0] + '")'
sql = ("select hour, sum(number) from " + table_name
+ ' where ((origin="' + pos[0] + '" and destination="' + pos[1] + '")'
+ opt_direction + ")"
+ ' and yearday>="' + sdate + '" and yearday<="' + edate+'" '
+ ' group by hour order by hour')
result = cur.execute(sql).fetchall()
for v in result:
count_data[v[0]][l] = v[1]
df = pd.DataFrame.from_dict(count_data)
df = df.T
df = df.reset_index()
fig = plt.figure( figsize=fig_size)
ax = fig.add_subplot(1, 1, 1)
ax = df.plot(ax=ax, fontsize=font_size, xticks=df.index, lw=4)
if legend_outside:
ax.legend(fontsize=font_size,loc='center left', bbox_to_anchor=(1.0, 0.5))
else:
ax.legend(fontsize=font_size)
ax.set_title("時間別移動アドレス数"+sub_title + " "+ sdate + " ~ " + edate, fontsize=font_size)
ax.set_xlabel("時間", fontsize=font_size)
ax.set_ylabel("アドレス数", fontsize=font_size)
if image_type !="":
if image_type=="emf": # 出力形式がemf指定のときは、svgにセーブしてからinkscapeで変換
plt.savefig(filename_body + ".svg" , bbox_inches="tight")
import subprocess
subprocess.run("inkscape --file " + filename_body + ".svg"
+ " --export-emf " + filename_body + ".emf", shell=True)
else:
plt.savefig(filename_body + "." + image_type, bbox_inches="tight")
plt.show()
def get_name_pairs(point_pairs, area="kofu"):
"""
[["12","22"], [ ], ... のような地点ペアを与えて、地点名をキーに入れて返す
"""
filename = {"kofu": "/var/www/html/kofu/sensor_points.csv",
"fuefuki": "/var/www/html/ff/sensor_points.csv",
"hakushu": "/var/www/html/hakushu/sensor_points.csv",
"ttri": "/home/toyotamngr/csv/toyota/sensor_points.csv"}
df = pd.read_csv(filename[area])
path = {}
for p in point_pairs:
if area == "kofu":
p0 = "kofu" + p[0]
p1 = "kofu" + p[1]
else:
p0 = p[0]
p1 = p[1]
key = (df[df.センサ名 == p0]['短縮名'].values[0] + " - "
+ df[df.センサ名 == p1]['短縮名'].values[0])
path[key] = [p[0], p[1]]
return path
地点(センサ)番号の一覧は附録に示す通り。
# 実行サンプル
# 駅南北
pairs = [["26", "27"], ["27", "26"], ["27", "28"], ["28","27"],["25","27"],["27", '25']] # 調べたい地点ペア
path = get_name_pairs(pairs)
plot_hourly_flow(path, "(甲府駅周辺)","KofuStationFlow", "emf", sdate="2019-08-01", edate="2019-12-31",
direction=True, legend_outside=True)
城東通りを例にした移動時間分布
# 所要時間ヒストグラムを作る関数定義
# DBへの接続手続きを最初に行う
# DBに格納されている観測開始日を、DBへの問い合わせSQLに埋め込み (dDateで)
# DB接続
import sqlite3
db_file = "/home/raspimngr/db/kofu_traveler.sqlite3" # ファイルの場所はそれぞれの環境に応じて変える
conn = sqlite3.connect(db_file)
# 8tops上のDBファイル (2019/03時点)
conn = sqlite3.connect("/home/raspimngr/db/kofu_traveler.sqlite3")
cur = conn.cursor()
def query(sql_str):
cur.execute(sql_str)
return cur.fetchall()
#####以上、DB接続######################
import pandas as pd
from datetime import datetime, timedelta
import matplotlib.pyplot as plt
%matplotlib inline
def showTravelTimeHistgram(origin, destination, hour_list,
bin_list = [0, 120, 240, 360, 480, 600, 900, 1200, 1800, 3600] # 区分(秒)
):
sql = ("select strftime('%H',dTime), aTime, dTime from traveler_all " +
"where dDate>='2019-10-20' " + " and origin='" + origin +
"' and destination='" + destination + "' and glbit=0")
result = query(sql)
raw_data = {}
hour = hour_list # 知りたい時間
for i in range(24):
raw_data[str(i).zfill(2)] = []
for d in result:
sec = (datetime.strptime(d[1], "%H:%M:%S") - datetime.strptime(
d[2], "%H:%M:%S")).total_seconds()
if sec < 10:
continue
raw_data[d[0]].append([d[1], d[2], sec])
# print(raw_data)
# 区分(値の区切り)
# ラベルを自動生成 (最後の値は多めにとってあるので、「以上」と記す)
bin_label = [str(bin_list[i])+"-"+str(bin_list[i+1]) for i in range(len(bin_list)-2)]
bin_label.append(str(bin_list[-2])+"以上")
hist_data = {}
# pandas DataFrame形式のデータ作成
for n, h in enumerate(hour):
# 時刻hのデータをDataFrame形式に
df_raw = pd.DataFrame(
raw_data[h], columns=["departure_time", "arrival_time", "travel_time"])
# bin_listで指定した区分のヒストグラムデータに
hist_data[n] = pd.cut(
df_raw["travel_time"], bins=bin_list, labels=bin_label,
right=False).value_counts(sort=False)
# センサー設置場所の名前取得
result = cur.execute("select * from sensor").fetchall()
sensor = {}
for v in result:
sensor[v[0]] = {'name': v[3], 'shortname': v[5], 'area': v[4]}
# 描画
fig_num_rows = int(len(hour) / 2)
fig = plt.figure(figsize=(12, 4 * fig_num_rows))
plt.subplots_adjust(wspace=0.4, hspace=0.6)
ax = []
for n, h in enumerate(hour):
ax.append(fig.add_subplot(fig_num_rows, 2, n + 1))
hist_data[n].plot.bar(ax=ax[n])
ax[n].set_title(sensor[origin]["shortname"]
+ " ⇒ " + sensor[destination]["shortname"]
+ "(" + h + "時台)", fontsize=14)
ax[n].set_xlabel("seconds", fontsize=14)
ax[n].set_ylabel("detected travelers", fontsize=14)
ax[n].xaxis.set_tick_params(rotation=30, labelsize=14)
# plt.savefig("flow_bousai_dan.svg")
plt.show()
#### main ###
#六曜館(23)とエスケイティ(32)間を移動した人の出発時刻と到着時刻の抽出
origin = "23"
destination = "32"
hour_list = ["06", "08", "12", "17", "19", "21"] # 調べたい時間帯
showTravelTimeHistgram(origin, destination, hour_list)
GoobleのAPIを通じて得られる2地点間の車での所要時間を取得する。
方法(プログラム)については、
https://toyoki-lab.ee.yamanashi.ac.jp/~toyoki/labTips/UseGoogleAPI.html
に書いてある通り。
2019/12/05より、平和通り県庁前交差点から甲府気象台東(飯田通りとアルプス通りの交差点)の所要時間を記録している。
つぎのようにしてみることができる。
# 8tops上で採取しているデータの閲覧
import pandas as pd
import matplotlib.pyplot as plt
from matplotlib.dates import DateFormatter # 時間軸のフォーマットを自在に
from datetime import datetime
fig, ax = plt.subplots(figsize=(8, 4))
df = pd.read_csv("/ssd/toyoki/googleData/iida/iidaBothTrafficByGoogle.csv",sep=",",skipinitialspace=True)
df['date'] = pd.to_datetime(df['date'], format='%Y/%m/%d %H:%M:%S')
df_part = df[(datetime(2020,1,1) < df['date']) & (df['date'] < datetime(2020,1,16))]
df_part.plot(x='date', y=['east_bound','west_bound'], figsize=(16,8), ax=ax)
ax.xaxis.set_major_formatter(DateFormatter('%m/%d'))
日々のデータを平均して、1日の時間変化をみるスクリプトは、城東通りの分析例を参考にする。(もちろん、自分で考えてみるのがよい。)
センサ一覧
import pandas as pd
filename = {"kofu": "/var/www/html/kofu/sensor_points.csv",
"fuefuki": "/var/www/html/ff/sensor_points.csv",
"hakushu": "/var/www/html/hakushu/sensor_points.csv",
"ttri": "/home/toyotamngr/csv/toyota/sensor_points.csv"}
pd.read_csv(filename["kofu"])