2地点間流動データの可視化

複数地点の比較

他のノートブックにもあるが、特に論文用の図を作成するためのもの

Microsoft Officeに張り込むにはemp形式にするのが望ましい。それを自動作成する。

In [61]:
# 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')
        # print(sql)
        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
                    

if __name__ == "__main__":
    # path = {}
    # path["奥藤 - 防災新館"] = ["22", "9"]
    # path["防災新館 - ダン"] = ["9", "17"]
    # path["ダン - 風月堂"] = ["3", "17"]
    # path["ブラザー - ルパン"] = ["13", "24"]
    # path["キュイエール - クラフト"] = ["16", "18"] # クラフトは2019年用なのでない
    pairs = [["22", "9"], ["9", "17"], ["13", "24"]]
    path = get_name_pairs(pairs)
    # print(path)
    plot_hourly_flow(path, "(一方向)","hourlyFlow", "emf", direction=True, legend_outside=True)
In [ ]:
 

甲府市中心街

In [62]:
# オリンピック通り(30)と周辺のつながり
pairs = [["30", "24"], ["30", "13"], ["30", "31"]]
path = get_name_pairs(pairs)
plot_hourly_flow(path, "(双方向)","olympicFlow", "emf", sdate="2019-10-01", edate="2019-12-31",
                 direction=False, legend_outside=True)
In [85]:
# 城東・舞鶴
pairs = [["9", "17"], ["17", "9"], ["17", "3"], ["3","17"]]
path = get_name_pairs(pairs)
plot_hourly_flow(path, "(城東通り、舞鶴通り)","JotoMaiduruFlow", "emf", sdate="2018-10-01", edate="2019-12-31",
                 direction=True, legend_outside=True)
In [89]:
# 駅南北
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)
In [100]:
# 春日モール・銀座通り
pairs = [["24", "13"], ["24", "19"], ["24", "11"],["24","20"]]
path = get_name_pairs(pairs)
plot_hourly_flow(path, "(春日・銀座)","GinzaKasugaFlow", "emf", sdate="2018-08-01", edate="2019-12-31",
                 direction=False, legend_outside=True)

特定地点間流動の月変化

描画のための関数定義

plot_hourly_flow_1seg(path, path_name, smonth="2019-08", emonth="2019-12", direction=True)

path, path_nameは、2地点IDの配列

In [97]:
# DB接続
import sqlite3
import pandas as pd
import matplotlib.pyplot as plt
from datetime import datetime, timedelta
from dateutil.relativedelta import relativedelta
import copy

# 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_1seg(path, path_name="", sub_title="", filename_body="temp", image_type="", direction=False,
                          smonth="2019-09", emonth="2020-02", legend_outside=False):
    count_data = {"00": 0, "01":0,"02": 0,"03": 0,"04": 0,"05": 0,"06": 0,"07": 0,"08": 0,"09": 0,
                 "10": 0,"11": 0,"12": 0,"13": 0,"14": 0,"15": 0,"16": 0,"17": 0,"18": 0,"19": 0,
                 "20": 0 ,"21": 0,"22": 0,"23": 0}
    count_data_both = copy.deepcopy(count_data)
    
    sday = "01"
    eday = {"01": "31", "02": "28", "03": "31", "04": "30", "05": "31", "06": "30",
            "07": "31", "08": "31", "09": "30", "10": "31", "11": "30", "12": "31"}
    font_size = 16

    if direction:
        #opt_direction = ''
        fig_size = (17,6)
    else:
        #opt_direction = ' or (origin="' + path[1] + '" and destination="' + path[0] + '")'
        fig_size = (8,6)
    
    flow_number = {} # 順方向データの入れ物
    flow_number2 = {} # 逆方向
    flow_number_both = {} # 双方向の和
    month = smonth
    dt_month = datetime.strptime(smonth+"-01", "%Y-%m-%d")
    while month <= emonth:
        sdate = month + "-" + sday
        edate = month + "-" + eday[month[-2:]]
        sql = ("select hour, sum(number) from " + table_name 
               + ' where (origin="' + path[0] + '" and destination="' + path[1] + '")'
               + ' and yearday>="' + sdate + '" and yearday<="' + edate+'" '
               + ' group by hour order by hour')
        
        result = cur.execute(sql).fetchall()
        sql2 = ("select hour, sum(number) from " + table_name 
               + ' where (origin="' + path[1] + '" and destination="' + path[0] + '")'
               + ' and yearday>="' + sdate + '" and yearday<="' + edate+'" '
               + ' group by hour order by hour')
        result2 = cur.execute(sql2).fetchall()
        
        for v in result:
            count_data[v[0]]= v[1] # 時ごとの流動数
            count_data_both[v[0]] = v[1]
        # print(count_data)
        flow_number[month] = copy.deepcopy(count_data)
        for v in result2:
            count_data[v[0]]= v[1] # 時ごとの流動数
            count_data_both[v[0]] += v[1]
        flow_number2[month] = copy.deepcopy(count_data)
        flow_number_both[month] = copy.deepcopy(count_data_both)
        
        dt_month = dt_month + relativedelta(months=1)
        month = datetime.strftime(dt_month, "%Y-%m") # 月をひとつ進める
        
    df = pd.DataFrame.from_dict(flow_number)
    df = df.reset_index()
    df2 = pd.DataFrame.from_dict(flow_number2)
    df2 = df2.reset_index()
    df_both = pd.DataFrame.from_dict(flow_number_both)
    df_both = df_both.reset_index()
    
    # 描画
    fig = plt.figure( figsize=fig_size)
    if direction:
        ax = fig.add_subplot(1,2,1)
        df.plot(ax=ax, fontsize=font_size, xticks=df.index, lw=4)
        ax.set_title(path_name[0] + " - " + path_name[1], fontsize=font_size)
        ax.legend(fontsize=font_size)
        ax2 = fig.add_subplot(1,2,2)
        df2.plot(ax=ax2, fontsize=font_size, xticks=df.index, lw=4)
        ax2.set_title(path_name[1] + " - " + path_name[0], fontsize=font_size)
        ax2.legend(fontsize=font_size)
    else:
        ax = fig.add_subplot(1, 1, 1)
        df_both.plot(ax=ax, fontsize=font_size, xticks=df.index, lw=4)
        ax.set_title(path_name[0] + " - " + path_name[1] + " (双方向)", fontsize=font_size)
        ax.legend(fontsize=font_size)
    # return(df,df2)

甲府

In [98]:
path = get_name_pairs([["9", "17"]], area="kofu")
# path辞書で、キーが地点名をハイフンでつないだ文字列、値が地点IDペアのリスト
# ここでは1つしかいらないのだが、forの繰り返しとする
for p in path:
    path_name = p.split("-") # 名称分解
    plot_hourly_flow_1seg(path[p], path_name, smonth="2019-08", emonth="2019-12", direction=True)

参考

In [35]:
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"])
#df = pd.read_csv(filename['kofu'])
#df[df.センサ名=="kofu7"]['短縮名'].values[0]
Out[35]:
センサ名 lat log 地点名 カテゴリ 短縮名
0 kofu1 NaN NaN NaN NaN NaN
1 kofu2 35.658933 138.571024 三枝豆店 中央 三枝豆店
2 kofu3 35.660988 138.571165 風月堂 中央 風月堂
3 kofu4 35.670632 138.565893 永田楽器 北口・朝日町 永田楽器
4 kofu5 35.662019 138.571818 文化のるつぼ Hechima 丸の内 るつぼ
5 kofu6 NaN NaN NaN NaN NaN
6 kofu7 35.666474 138.567104 ライフインナカゴミ 丸の内 ライフイン
7 kofu8 35.669087 138.566179 オスカー本社・朝日店 北口・朝日町 オスカー
8 kofu9 35.663483 138.568223 防災新館1F 丸の内 防災新館
9 kofu10 35.660508 138.571015 河野スポーツ 中央 河野
10 kofu11 35.658980 138.569654 内藤セイビドー眼鏡店 中央 セイビドー
11 kofu12 35.665457 138.567812 立ち食い焼肉 鷹の 丸の内 鷹の
12 kofu13 35.659908 138.571535 ブラザー(文房具) 中央 ブラザー
13 kofu14 35.666835 138.571457 甲州夢小路 北口・朝日町 夢小路
14 kofu15 NaN NaN NaN NaN NaN
15 kofu16 35.662705 138.570433 甲府クラフトラボ 丸の内 クラフトラボ
16 kofu17 35.661394 138.568810 ダン珈琲店 中央 ダン
17 kofu18 35.662433 138.569498 カフェ・キュイエール 丸の内 キュイエール
18 kofu19 35.660883 138.570182 きぬや 中央 きぬや
19 kofu20 35.660050 138.569150 そば処 奥義 中央 奥義
20 kofu21 35.671693 138.566729 玉屋 北口・朝日町 玉屋
21 kofu22 35.665733 138.568327 奥藤本店 丸の内 奥籐
22 kofu23 35.665305 138.567282 六曜館珈琲店 本店 丸の内 六曜館
23 kofu24 35.660092 138.570098 ルパンザバール ワイン酒場前 中央 ルパン
24 kofu25 35.666321 138.568691 甲府駅南口 甲府駅周辺 駅南口
25 kofu26 35.667769 138.570091 藤村記念館 甲府駅周辺 藤村
26 kofu27 35.667481 138.569165 甲府駅北口コンコース 甲府駅周辺 駅北口
27 kofu28 35.666682 138.567703 甲府駅南口第1駐輪場 甲府駅周辺 第1駐輪場
28 kofu29 35.666348 138.570488 甲府駅南口第2駐輪場 甲府駅周辺 第2駐輪場
29 kofu30 35.658877 138.569747 オリンピック通 中央 オリンピック通
30 kofu31 35.657720 138.569734 甲府商工会義所 中央 商工会議所
31 kofu32 35.668393 138.555370 エスティケイ 飯田 エスティケイ
In [ ]: