ふるさと納税の寄附金額を地図上で可視化する

先日、世田谷区がふるさと納税で税収41億円減というニュースがありました。保坂区長は愚策中の愚策とおっしゃっててかなりご立腹の様子です。

www.zeiri4.com

じゃあこのふるさと納税で集まったお金、いったいどこの自治体に回ってるんでしょうか。ふるさと納税関連のデータは総務省が取りまとめていて、以下の『ふるさと納税トピックス』にデータが落ちてます。

総務省|ふるさと納税ポータルサイト|トピックス|平成30年度ふるさと納税に関する現況調査について

データはExcelなのでソートしやすいですが、全国どのあたりに分布しているかを調べたい場合は地図で可視化したほうが良いです。なのでGISの力を使ってちゃちゃっと可視化してしまいましょう。

白石さんが先に可視化をやってらっしゃったので完全に二番煎じです。

使うツール類

今回はAnacondaのPython環境+ArcGIS Onlineを使用します。Anacondaがなくても以下の環境が整っていればOKです。

オープンソースでやりたかったけど手慣れてる環境の方が圧倒的に早いのでArcGIS使ってます。

ArcGIS Onlineは有償のGISクラウドサービスで、メールアドレスがあれば以下のアドレスから21日分のトライアルライセンスが発行できます。Tableauとかでも出来るような気もします*1

www.esri.com

Python環境のインストール方法はググるといくらでも出てくるので割愛します。

Anacondaのような環境まるごとインストールじゃない場合はpandasは入らないので、別途pipを使ってインストールしましょう。arcgisのライブラリもpip経由で導入できますが、Anacondaを使う場合にはcondaでインストールしたほうが良いです*2

標準python環境だとpipでインストール。

pip install pandas
pip install arcgis

Anaconda環境ではpandasは入っているのでcondaでarcgisだけインストール。

conda install -c esri arcgis

ここまでの準備が出来たら実際の可視化に取組みます。Anaconda環境のjupyter notebookで進めていきます。

Excelデータのダウンロード・読み込み

先程の総務省URLから『ふるさと納税に関する現況調査結果(都道府県・市区町村別)集計結果』のExcelをダウンロードします。ダウンロードしたフォルダで作業するのが悩まなくて楽。ダウンロードフォルダとは別環境でやる場合は適宜読み替えてください。

まず必要なライブラリをインポートします。

import pandas as pd
from arcgis import GIS
from getpass import getpass

getpassは以降貼り付けるキャプチャの見られたらヤバイ部分を秘匿するために使ってます。

pandasでダウンロードしてきたExcelを読み込みます。read_excelを使うだけなのでお手軽。

df = pd.read_excel('./results20180706-02.xlsx', skiprow=4)

先頭4行はいらないのでskiprow=4で飛ばします。df.head()で中身を見てみましょう。

f:id:kazutaka83:20180805134625p:plain

列1~列3はセルの結合をしているのでカラム名が取れてません*3。放って置くと出来上がるデータが汚くなるので対処します。

df = df.rename(columns={"Unnamed: 0":"自治体コード"})
df = df.rename(columns={"Unnamed: 1":"都道府県"})
df = df.rename(columns={"Unnamed: 2":"市町村名"})

この後市町村名でジオコーディング*4をかけて行きますが、このままだと北区・板橋区が台湾の方に飛んでいきます。なのでジオコーディング用の住所を作成します。

df["ジオコーディング用住所"] = df["都道府県"] + df["市町村名"]

これでアップロード用のDataFrameが出来ました。

ArcGIS Onlineにアップロード

作成したDataFrameをArcGIS Onlineのアップロードします。必要なのはArcGIS OnlineのURL、ユーザ名、パスワード。

gis = GIS("https://<取得したドメイン>.maps.arcgis.com",  "<ユーザ名>", "<パスワード>"

f:id:kazutaka83:20180805005703p:plain

このgisを使って諸々の作業をやっていきます。全部の列はいらないので今回は寄附金額、寄附件数だけをアップロードします。locを使ってDataFrameから必要な部分を取り出し、ジオコーディング用住所をジオコード。

gis の content.import_data は pandas の DataFrame を食ってくれます。df.loc でアップロードする箇所を示し、第二引数で住所のフィールドを指定します。今回は {"Address":"住所"} で指定してますが、国別統計値を扱う場合は {"Country":"国名"} という感じで記載します。

# アップロード内容の確認(ipython, jupyter用)
df.loc(1:1000, ["自治体コード", "都道府県", "市町村名", "ジオコーディング用住所" "寄附件数", "寄附金額"]])
fc = gis.content.import_data(df.loc[1:1000, ["自治体コード", 
                                             "都道府県", 
                                             "市町村名", 
                                             "ジオコーディング用住所", 
                                             "寄附件数", 
                                             "寄附金額"]],
                                             {"Address":"ジオコーディング用住所"})

f:id:kazutaka83:20180805005740p:plain

loc で1行目から1,000行目までを指定しているのは import_data の上限が1,000件だからです。DataFrame 直投げ込みは便利なんですがこういう制限があります。

arcgis.gis module — arcgis 1.5.0 documentation

この fc は処理用のインメモリデータで、そのままだと消えるのでアイテムとして登録します。

import json
item_properties = {
    "title": "総務省ふるさと納税レポート",
    "tags" : "自治体,納税,可視化",
    "snippet": " ふるさと納税の可視化",
    "description": "ふるさと納税データをArcGIS Online上で可視化",
    "text": json.dumps({"featureCollection": {"layers": [dict(fc.layer)]}}),
    "type": "Feature Collection",
    "typeKeywords": "Data, Feature Collection, Singlelayer",
    "extent" : "-102.5272,-41.7886,172.5967,64.984"
}
item = gis.content.add(item_properties)

これでクラウド上にアップロード出来ました(1,000件だけですが)。ArcGIS Onlineにログインしてコンテンツタブを開くとデータが登録されていると思います。

f:id:kazutaka83:20180805012349p:plain

jupyter notebook を使っている場合、このデータを notebook 上で確認することができます。gis.map() を使って地図を表示し, そこに fc を追加します。map の引数に住所を与えるとその場所にフォーカスした地図が出てきます*5

furusato_map = gis.map('JAPAN')
furusato_map.add_layer(fc)
furusato_map

f:id:kazutaka83:20180805140925p:plain

ポイントがそのまま落ちてるはイマイチなので表示を切り替えます。add_layer に表示形式を加えます。

furusato_map = gis.map('JAPAN')
furusato_map.add_layer(fc, {"renderer":"ClassedSizeRenderer", "field_name": "寄附金額"})
furusato_map

ちょっとキモい。

f:id:kazutaka83:20180805141508p:plain

サービスの加工と残データの追加

Feature Collectionのままだと使いにくいので加工します。

search_item = gis.content.search('総務省ふるさと納税レポート')
fc2 = search_item[0]
fc2.publish()

これで使いやすい形式になりました。content.search() を使って新規データを取りに行きます。

search_item2 = gis.content.search('総務省ふるさと納税レポート',item_type='Feature Layer Collection')

で、このデータに残りの700行ちょいを足します。残りのデータはテンポラリで良いので fc3 という名前で適当に上げます。

fc3 = gis.content.import_data(df.loc[1001: , ["自治体コード", 
                                             "都道府県", 
                                             "市町村名", 
                                             "ジオコーディング用住所", 
                                             "寄附件数", 
                                             "寄附金額"]],
                                             {"Address":"ジオコーディング用住所"})

flc = search_item2[0]
flc.layers[0].edit_features(adds=fc3.query())

結合するために edit_features(adds=hoge) を使ってます。

f:id:kazutaka83:20180805013904p:plain

これで全部のデータが上がりました。

見栄えの調整

データをマップビューアで開いてみると全国に点が落ちてます。

f:id:kazutaka83:20180805175657p:plain

左側のスタイル設定から見栄えを調整、メニューのベースマップから背景地図を設定できます。

f:id:kazutaka83:20180805175602p:plain

Webマップなのでブログに貼り付けも可。ポイントを触ると寄附金額や件数がポップアップで表示されます。

あとは3次元での表示も。

3次元地図は右クリック長押しで3D回転が効きます。

平成28年度は北海道が強かったんですが、去年は大阪、九州が強いんですね。 地図化すると中々面白いです。

www.esrij.com

*1:誰かやって

*2:jupyter notebookの可視化で問題が起きることがあるため

*3:セルを結合する輩とは仲良くなれない気がする

*4:緯度経度付与のこと

*5:引数次第で縮尺レベルの指定も出来る


スポンサード リンク