背景
先人たちの知恵をお借りするなどして解決できたことを、この場をお借りして感謝するとともに、大変恐縮ですが自分のメモとして、こちらへまとめておきます。
はじめに
今回使用する環境等のバージョン
Windows 11 Pro 23H2
Python 3.12.5
QGIS 3.34.8
1.背景
オープンデータをつかってデータの可視化をする中、ぱっとデータの感じを掴む上で、位置情報をもつデータについて、地図上へのプロットをもっと簡単にできないだろうか?と思うことはありませんか?
QGISやKepler.glで位置情報をもつデータを簡単に地図上にプロットできると聞き、早速、使ってみました。
2.QGISとは
そもそもGISって?
地理情報システム(GIS:Geographic Information System)は、地理的位置を手がかりに、位置に関する情報を持ったデータ(空間データ)を総合的に管理・加工し、視覚的に表示し、高度な分析や迅速な判断を可能にする技術
国土交通省国土地理院のページより引用
QGIS
QGIS(Quantum GIS)は、地理空間情報データを扱う地理情報システム(GIS)がフリーで利用できるオープンソースのソフトウェア。
地図上でのデータの閲覧、編集、分析を行うことができる優れもの。
インストール方法はコチラ
3.Kepler.glとは
Uber社が開発したオープンソースの地理情報可視化ツール(webGIS)。
緯度や経度を含むCSVやJSONデータをアップロードすることで、プログラミングスキルを必要とせずに地図データを可視化でき、また、時刻情報が含まれている場合はアニメーションも作成できます。
3.実践
「交通事故統計情報のオープンデータ」(警察庁)(https://www.npa.go.jp/publications/statistics/koutsuu/opendata/index_opendata.html
)の2019年~2023年分をダウンロードします。
今回はそのうちの本票_01-12月データ(2023年分は「honhyo_2023.csv」というファイル名)を使います。
つづいてデータに前処理を施します。
pythonで発生日時と、緯度・経度の項目値を整備します。
import pandas as pd
# 年ごとのcsvファイルを読み込んでdataframeに
d1 = pd.read_csv('./2019/data/honhyo_2019.csv', encoding="cp932", index_col=0)
d2 = pd.read_csv('./2020/data/honhyo_2020.csv', encoding="cp932", index_col=0)
d3 = pd.read_csv('./2021/data/honhyo_2021.csv', encoding="cp932", index_col=0)
d4 = pd.read_csv('./2022/data/honhyo_2022.csv', encoding="cp932", index_col=0)
d5 = pd.read_csv('./2023/data/honhyo_2023.csv', encoding="cp932", index_col=0)
df = pd.concat([d1, d2, d3, d4, d5])
# 発生年月日時分を1カラムに集約してdatetime型に
df = df.astype({"発生日時 年": str, "発生日時 月": str, "発生日時 日": str, "発生日時 時": str, "発生日時 分": str,})
df["Datetime"] = pd.to_datetime(df["発生日時 年"]+"-"+df["発生日時 月"]+"-"+df["発生日時 日"]+"T"+df["発生日時 時"]+":"+df["発生日時 分"])
# 緯度・経度(世界測地系)の分秒を60進から10進に変換し、小数表記にして文字列型に
# ex) 431007628, 1410328320 -> 43.16878555555555, 141.05786666666668
def dms2deg(df, col):
df2 = df.copy()
df2["d"], df2["t"] = df2[col].divmod(10000000)
df2["m"], df2["s"] = df2['t'].divmod(100000)
converted = df2["d"] + (df2["m"] / 60.0) + (df2["s"] / 1000.0 / 3600.0)
return converted
df['lat'] = 0
df['lon'] = 0
df['lat'] = dms2deg(df, '地点 緯度(北緯)')
df['lon'] = dms2deg(df, '地点 経度(東経)')
# csvファイルで出力
df.to_csv('./all/data/honhyo_all_latlon.csv')
上記で出力したcsvデータを、QGIS、kepler.glにそれぞれ読み込ませます。
使い方はそれぞれのdocumentを参照ください。
4.結果
以下はすべて、「交通事故統計情報のオープンデータ」(警察庁)(https://www.npa.go.jp/publications/statistics/koutsuu/opendata/index_opendata.html
)を加工して作成
※ 5年分の事故発生位置を緯度・経度から地図上にプロットしたのみで、事故の種別や被害者の数などに関係なく同じ色でしめしています。
色の濃淡があるのは、同じ場所やごく近い場所で発生した場合に重ねてプロットしているためです。
- 1)千葉県市川市の南部
大きな通りや細くても交通量の多そうな通り、交差点に集中しているように見えます。
(1つ1つの点は不透明度70%で描画)
- 2)関東地方
都市部など人口が多く道路網が密集している地域に、事故は集中することが分かります。
反対に、山間部など道路網が密集しておらず都市部に比べて交通量の少ない場所は事故も相対的に少ないようです。
(1つ1つの点は不透明度40%で描画)
- 3)本州
関東地方と同様に、都市部など人口が多く道路網が密集している地域に事故は集中し、反対に、山間部など道路網が密集しておらず都市部に比べて交通量の少ない場所は事故も相対的に少ない傾向が見えます。
(1つ1つの点は不透明度40%で描画)
参考
(編集後記)
今回は単に事故発生位置を緯度・経度から地図上にプロットしたのみでしたが、発生日時から曜日別・時間帯別や月別・季節ごとの発生数、事故累計や天候、地形、路面応対、道路形状などの項目から、データを集計して、グラフ等に可視化することで、事故の傾向なども見えてくるかと思います。
BIダッシュボードの機能をもつツールやライブラリを用いて、データの可視化について引き続き学習をすすめていきます。