PythonでGoogleMapsApiを使って、Bリーグでの試合間移動距離を可視化する

# はじめに

Bリーグでは試合日程が結果に影響するのだろうか、と下記で移動距離と勝敗データを見てみました。
https://note.mu/nanako_ut/n/n69e27420c63b

データとソースを、備忘録がてら記録します。

# GoogleMapsApiを使ってみよう
## GoogleMapsApiを使うためのキーを取得

- こちらを参考にGoogleMapsApiキーを取得

https://www.zenrin-datacom.net/business/media/g001/index.html

- pythonからGoogleMapsApiを利用するためのライブラリをインストール

https://github.com/googlemaps/google-maps-services-python

- GoogleMapsApiを使ってみる

2地点間の距離を取得（徒歩の場合）

```python
import googlemaps
from datetime import datetime

gmaps = googlemaps.Client(key='取得したAPIキー')

now = datetime.now()
directions_result = gmaps.directions("千葉県船橋市習志野台７丁目５−１", 
                                     "北海道札幌市豊平区豊平５条１１丁目１−１",
                                     mode="walking",
                                     departure_time=now)

directions_result[0]['legs'][0]['distance']['text']

---------------------------------------
出力結果
'1,032 km'
```

googlemapで試してみた結果も同じ
（「徒歩」指定で海を越える場合どうなるのか？と思ったが、船を使う前提になっていました）
![image.png](https://qiita-image-store.s3.amazonaws.com/0/170139/d9a1e7c7-b5a2-dbf3-1abc-12e8227deb16.png)

modeは、"driving", "walking", "bicycling" or "transit" の4種類の指定が可能である模様

# Bリーグのデータを可視化する
## データ
https://github.com/nanako-ut/basketball/blob/master/B-stats.csv

## 定義、関数
```python
import pandas as pd
import numpy as np
import seaborn as sns
import matplotlib.pyplot as plt
%matplotlib inline
```

### 指定した住所から２地点間の距離を取得する

始点と終点が同じだとエラーになるので、始点＝終点なら距離０とする

```python
gmaps = googlemaps.Client(key='取得したAPIキー')

def get_distance(ad_prev, ad_next):
    # 始点と終点が同じだとエラーになるので、始点＝終点なら距離０とする
    if ad_prev == ad_next:
        distance = '0 km'
    else:
        now = datetime.now()
        directions_result = gmaps.directions(ad_prev,
                                             ad_next,
                                             mode="walking",
                                             departure_time=now)
        distance = directions_result[0]['legs'][0]['distance']['text']
    
    return distance
```

### 指定したチームのデータを取得する

```python
def get_tearm_data(df, team_name):
    df_sec = df.query('team_name == @team_name').copy()

    # 日程順にソート
    df_sec.loc[0:, 'date_DT'] = pd.to_datetime(df_sec.loc[0:, 'date'], format='%Y/%m/%d')
    df_sec = df_sec.sort_values('date_DT').reset_index(drop=True)

    # キョリを算出
    df_sec['distance_s'] = '0 Km'
    df_sec['distance'] = 0
    df_sec['accum'] = 0
    for index, row in df_sec.iterrows():
        if index > 0 :
            # 距離を取得
            distance = get_distance(df_sec.loc[index-1, 'address'] , df_sec.loc[index, 'address'])
            df_sec.loc[index, 'distance_s'] = distance
            # google map apiから「9,999 km」と返ってくるので、文字列から数値に変換する
            df_sec.loc[index, 'distance'] = float(distance.replace(' km','').replace(',',''))
            df_sec.loc[index, 'accum'] = df_sec.loc[index-1, 'accum'] + df_sec.loc[index, 'distance']
    
    return df_sec
```

### チーム名

```python
team_name = [
    '千葉ジェッツ',
    '秋田ノーザンハピネッツ',
    '三遠ネオフェニックス',
    '滋賀レイクスターズ',
    'レバンガ北海道',
    'アルバルク東京',
    '名古屋ダイヤモンドドルフィンズ',
    '富山グラウジーズ',
    'ライジングゼファー福岡',
    '新潟アルビレックスBB',
    '栃木ブレックス',
    '川崎ブレイブサンダース',
    '京都ハンナリーズ',
    '大阪エヴェッサ',
    '琉球ゴールデンキングス',
    'シーホース三河',
    'サンロッカーズ渋谷',
    '横浜ビー・コルセアーズ']
```

## チーム別の距離データを取得し、csvに保存する

```python
# 試合結果のデータを読み込む
df = pd.read_csv('B-stats.csv')

#df_data = pd.DataFrame()

# 距離を付与したチームデータを取得
for team in team_name:
    df_sec = get_tearm_data(df, team)
    if team == "千葉ジェッツ":
        df_data = df_sec
    else:
        df_data = pd.concat([df_data, df_sec])

# インデックスを振り直し
df_data.reset_index(drop=False)

# ファイルに出力
df_data.to_csv('B-stats_distance.csv')
```

## 可視化

### 散布図

全チーム、各試合毎の、移動距離と総得点を散布図にプロットする

```python

# 距離を付与したデータを読み込む
df_data = pd.read_csv('B-stats_distance.csv')


# 散布図
## 得点の型をint型へ
df_data['score_int'] = df_data['score'].astype(np.int64)

## フォントを指定
sns.set(font='IPAexGothic')

sns.lmplot(x="distance", y="score_int", size=6, hue="result", scatter=True, fit_reg=False, data=df_data, markers=["x", "o"])
plt.xlabel('距離')
plt.ylabel('総得点')
plt.show()
```

**出力結果**
![image.png](https://qiita-image-store.s3.amazonaws.com/0/170139/32fcfe9c-e451-97f0-c53c-0f07a48fcbd3.png)



### 棒グラフ

各チーム別の移動距離を棒グラフで見てみる

```python
# 距離を付与したデータを読み込む
df_data = pd.read_csv('B-stats_distance.csv')

# チーム別の総移動距離を求める
df_sec = df_data.groupby('abbr_team_name').sum()

# 棒グラフ
plt.figure(figsize=(10, 5))
# フォントを指定
sns.set(font='IPAexGothic')

# 文字を少し大きく（"paper"<"notebook"<"talk"<"poster")
sns.set_context("talk")
sns.barplot(x=df_sec.index, y='distance', data=df_sec)
plt.xlabel('チーム')
plt.ylabel('距離')
plt.show()
```
**出力結果**

![image.png](https://qiita-image-store.s3.amazonaws.com/0/170139/8faa5b35-2955-39f6-b385-cf61967d282d.png)

# ソース
ソースとデータはこちら
https://github.com/nanako-ut/basketball/blob/master/B-stats.csv
https://github.com/nanako-ut/basketball/blob/master/B-LEAGUE-Analyze.ipynb


# 参考

下記を参考に、事前に日本語フォントを追加しました

[【Seaborn】日本語を表示する (フォントを変更する)](https://qiita.com/keisuke-nakata/items/2309764d21438645f6b9)