文京区の子どもの予防接種_指定医療機関一覧をTableauでマッピングしてみる

こんにちは。

先日は文京区の保育園内定指数を2回マッピングしてみました。

data-analytics.hatenablog.com

data-analytics.hatenablog.com

 

今回はTableauのマップ機能を使って、文京区の子どもの予防接種_指定医療機関一覧を地図上にプロットしてみたいと思います。

 

というのも、文京区の子どもの予防接種の指定医療機関一覧も、前回同様PDFの表で表現されていて、ぱっと見どこにあるのかわからないのです。

こういうのを地図上に表示させて、かつどの予防接種がうけられるかまで表現できれば、かなり便利かなと思います。

■文京区_子どもの予防接種の指定医療機関一覧

https://www.city.bunkyo.lg.jp/var/rev0/0208/8407/030104kodomo.pdf

f:id:kei_t__0107:20210114165113p:plain

 

流れとしては以下の通りです。

  1. 文京区_子どもの予防接種の指定医療機関一覧のPDFデータをテーブルデータに変換する
  2. 医療機関の住所情報から緯度経度情報を加える
  3. Tableau上でマッピング&ビジュアライズ

 

文京区_子どもの予防接種の指定医療機関一覧のPDFデータをテーブルデータに変換する

上記PDFをWordで保存⇒表部分をExcelに張り付けて整形しました。

令和3年1月4日時点のものです。

「030104kodomo.xlsx」という名前にしました。

※後ほど緯度経度を加えるため、住所に東京都文京区を加えた「住所変換」という列を追加してます。

f:id:kei_t__0107:20210114165737p:plain

 

医療機関の住所情報から緯度経度情報を加える

前の記事にも書きましたが、Tableauで地図情報を表現する場合、都道府県や区レベルまでなら文字情報で問題ないのですが、 町域や丁目・番地・号レベルでのマッピングになると緯度経度や郵便番号が必要になります。

医療機関所在地毎に緯度経度を付加したく、今回は以下のサイトからAPIを経由してジオコーディングしたいと思います。

※前回は番地レベルで簡単に付与しましたが、番地が被るものが結構あったので、今回はAPIを使って号レベルで一気に付与したいと思います

 

以下のGeocodingという無料のジオコーディングAPIサービスを利用します。

www.geocoding.jp

 

今回はPythonを使ってAPIから緯度経度情報を一括で持ってきたいと思います。

コーディング方法はこちらを参考にさせて頂きました。

qiita.com

 

実行環境はWindows10で、Anacondaをインストールして実行しました。

import requests
from bs4 import BeautifulSoup
import time
import tqdm
import pandas as pd

URL = 'http://www.geocoding.jp/api/'

#複数住所から緯度経度取得
def coordinate(address):
     """
    addressに住所を指定すると緯度経度を返す。
    
    >>> coordinate('東京都文京区本郷7-3-1')
    ['35.712056', '139.762775']
    """
    payload = {'q': address}
    html = requests.get(URL, params=payload)
    soup = BeautifulSoup(html.content, "html.parser")
    if soup.find('error'):
        raise ValueError(f"Invalid address submitted. {address}")
    latitude = soup.find('lat').string
    longitude = soup.find('lng').string
    return [latitude, longitude]


def coordinates(addresses, interval=10, progress=True):
    """
    addressesに住所リストを指定すると、緯度経度リストを返す。
    
    >>> coordinates(['東京都文京区本郷7-3-1', '東京都文京区湯島3丁目30−1'], progress=False)
     [['35.712056', '139.762775'], ['35.707771', '139.768205']]
    """
    coordinates = []
    for address in progress and tqdm(addresses) or addresses:
        coordinates.append(coordinate(address))
        time.sleep(interval)
    return coordinates


#医療機関リストファイル読み込み
df = pd.read_excel(r"***\030104kodomo.xlsx") #***の部分は030104kodomo.xlsxファイルを置いている場所

#APIから緯度経度付与
latlon_list = coordinates(df.loc[:, "住所変換"], progress=False)

#元のdfに緯度経度を結合,latlon_listはリスト形式で普通にやると結合できないのでpd.DataFrame形式に変換する
df = pd.concat([df, pd.DataFrame(latlon_list, columns=["緯度","経度"])], axis=1)

#出力
df.to_excel(r"***\030104kodomo_update.xlsx", index=False) #***の部分は030104kodomo_update.xlsxファイルを出力した場所

 ※TableauではなくPythonマッピングまですればよいのでは?と思った方もいらっしゃるかもですが、Tableau DATA Saber Boot Campの一環でこの記事を書いています

 

 上記が上手くできると、以下のような形でファイルが出力されます。

f:id:kei_t__0107:20210114220833p:plain

ただ、予防接種の名前が微妙におかしいので(I不P活V化ポリオとかになってる。PDF読み込み時のエラー)、手修正します。

f:id:kei_t__0107:20210115111243p:plain

これで下準備完了です。

Tableau上でマッピング&ビジュアライズ

いよいよTableauで読み込みます。

読み込んだら、予防接種の部分を後で使いやすいようにピボット(横持ち⇒縦持ち)します。

◇ピボット前

f:id:kei_t__0107:20210115114849p:plain

◇ピボット後

f:id:kei_t__0107:20210115115135p:plain

 

あとは医療機関を予防接種の実施数で色分けできるようにしたいので、○×形式になっている実施有無を数値(0/1)に変換しておきます。

f:id:kei_t__0107:20210115115638p:plain

 

最後に地図上にマッピングしていきます。「文京区_予防接種対応医療機関マップ」というシートです。

  • 地理的役割を追加した上で列に「経度」、行に「緯度」追加⇒マップ自動生成
  • マップレイヤーでスタイル:ストリート、ウォッシュアウト70%で設定
  • 医療機関名」「住所」「電話番号」をマークの「詳細」に追加
  • 「予防接種実施数」をマークの「色」に追加。色合いを指数が高いほど濃く、低いほど薄く表現する
  • 別途「予防接種実施有無」というシートを作り、「予防接種名」を行に、「実施有無」(○×がついた列)をマークの「形状」「色」に追加。○は赤、×は青、形状も一致させる。
  • 上記のシートを「ツールヒント」内に挿入する ※緯度経度も外しておく
  • 「文京区_予防接種対応医療機関マップ」「予防接種実施有無」ダッシュボード化して連動させる

f:id:kei_t__0107:20210115142650p:plain

f:id:kei_t__0107:20210115142431p:plain

f:id:kei_t__0107:20210115142909p:plain

地図上の医療機関をクリックしたりマウスオーバーすると、詳細データや各予防接種の実施状況が表示される

 

全て出来上がるとこちらになります。

地図上の医療機関をクリックしたりマウスオーバーすると、詳細データや各予防接種の実施状況が表示されます。また、各予防接種の実施状況は右側にも表示されます。

f:id:kei_t__0107:20210115143505p:plain



ご自身で動かしてみたい方はこちらをご覧ください。

 

 

 

 ※詳細はこちらでもご覧いただけます

public.tableau.com



いかがでしたでしょうか? 感想などありましたら、コメントに記載いただくか上記のTableau・Publicからコンタクトくださいませー。 ではでは。