地理データの可視化
Contents
地理データの可視化#
本節では緯度・経度の情報をもつ、地理データを可視化する手法を学びます。
国土交通省のGISホームページから、滋賀県の地価公示データを取得します。
https://nlftp.mlit.go.jp/ksj/old/datalist/old_KsjTmplt-L01.html
!wget https://nlftp.mlit.go.jp/ksj/old/data/L01/L01-2022P/L01-2022P-25-01.0a.zip
!unzip -o L01-2022P-25-01.0a.zip
--2022-11-19 05:51:51-- https://nlftp.mlit.go.jp/ksj/old/data/L01/L01-2022P/L01-2022P-25-01.0a.zip
Resolving nlftp.mlit.go.jp (nlftp.mlit.go.jp)... 192.29.39.162, 192.29.39.48, 192.29.41.65
Connecting to nlftp.mlit.go.jp (nlftp.mlit.go.jp)|192.29.39.162|:443... connected.
HTTP request sent, awaiting response... 200 OK
Length: 55443 (54K) [application/zip]
Saving to: ‘L01-2022P-25-01.0a.zip’
L01-2022P-25-01.0a. 100%[===================>] 54.14K --.-KB/s in 0.005s
2022-11-19 05:51:51 (11.7 MB/s) - ‘L01-2022P-25-01.0a.zip’ saved [55443/55443]
Archive: L01-2022P-25-01.0a.zip
creating: L01-2022P-25-01.0a/
inflating: L01-2022P-25-01.0a/KS-META-L01-2022P-2K_25.xml
inflating: L01-2022P-25-01.0a/L01-2022P-25-01.0a.html
inflating: L01-2022P-25-01.0a/L01-2022P-2K_25.csv
from io import StringIO
import json
import pandas as pd
import plotly.express as px
shiga_land_price = pd.read_csv("./L01-2022P-25-01.0a/L01-2022P-2K_25.csv", encoding="cp932")
shiga_land_price.loc[:, ["経度", "緯度"]] = shiga_land_price.loc[:, ["経度", "緯度"]] / 3600
shiga_land_price.head()
| 経度 | 緯度 | 所在地コード | 用途 | 連番 | 年次 | 前年所在地コード | 前年用途 | 前年連番 | 市区町村名 | ... | 属性移動H25 | 属性移動H26 | 属性移動H27 | 属性移動H28 | 属性移動H29 | 属性移動H30 | 属性移動H31 | 属性移動R2 | 属性移動R3 | 属性移動R4 | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | 135.911983 | 35.108868 | 25201 | 0 | 1 | 2022 | 25201 | 0 | 1 | 大津 | ... | 40000000000000 | 10000000000000 | 10000000000000 | 10000000000000 | 10000000000000 | 10000000000000 | 10000000000000 | 10000000000000 | 10000000000000 | 10000000000000 |
| 1 | 135.915560 | 35.122949 | 25201 | 0 | 2 | 2022 | 25201 | 0 | 2 | 大津 | ... | 10000000000000 | 10000000000000 | 10000000000000 | 10000000000000 | 10000000000000 | 10000000000000 | 10000000000000 | 10000000000000 | 10000000000000 | 10000000000000 |
| 2 | 135.900566 | 35.097219 | 25201 | 0 | 3 | 2022 | 25201 | 0 | 3 | 大津 | ... | 10000000000000 | 10000000000000 | 10000000000000 | 10000000000000 | 10000000000000 | 10000000000000 | 10000000000000 | 10000000000000 | 10000000000000 | 10000000000000 |
| 3 | 135.876694 | 35.074805 | 25201 | 0 | 4 | 2022 | 25201 | 0 | 4 | 大津 | ... | 10000000000000 | 10100000000000 | 10000000000000 | 10000000000000 | 10000000000000 | 10000000000000 | 10000000000000 | 10000000000000 | 10000000000000 | 10000000000000 |
| 4 | 135.972987 | 35.251884 | 25201 | 0 | 5 | 2022 | 25201 | 0 | 5 | 大津 | ... | 20000000000000 | 20000000000000 | 10000000000000 | 10000000000000 | 10000000000000 | 10000000000000 | 10000000000000 | 10000000000000 | 10000000000000 | 10000000000000 |
5 rows × 126 columns
散布図#
Plotly Expressの scatter_mapbox 関数を利用して、地図上に散布図を描画します。
data_frame(第1引数): 描画対象のDataFrame
lat: 緯度が格納されている列名
lon: 経度が格納されている列名
size: 要素の大きさをとなる列名
color: 要素の色となる列名
hover_name: ホバーツールのタイトルとなる列名
hover_data: ホバーツールに表示するデータとなる列名
height: 描画領域の高さ
center: 中心となる位置を辞書で指定(lat: 緯度, lon: 経度)
zoom: 縮尺
scatter_mapbox 関数はmapboxというサービスのAPIを利用しています。デフォルトを含め、いくつかのスタイルはmapboxのアクセストークンを渡す必要がありますが、トークンを必要としないスタイル( layout.mapbox.style )もあります。
layout.mapbox.stylehttps://plotly.com/python/mapbox-layers/
mapboxアカウントは無料で作成でき、アカウント画面からアクセストークンが生成できます。
https://account.mapbox.com
px.scatter_mapbox(
shiga_land_price,
lat="緯度",
lon="経度",
size="R4価格",
color="用途区分",
hover_name="市区町村名",
hover_data=["所在並びに地番"],
center={"lat": 35.09, "lon": 136.18},
opacity=0.5,
width=800,
height=800,
mapbox_style="carto-positron",
).show()
shiga_land_price.columns
Index(['経度', '緯度', '所在地コード', '用途', '連番', '年次', '前年所在地コード', '前年用途', '前年連番',
'市区町村名',
...
'属性移動H25', '属性移動H26', '属性移動H27', '属性移動H28', '属性移動H29', '属性移動H30',
'属性移動H31', '属性移動R2', '属性移動R3', '属性移動R4'],
dtype='object', length=126)
shiga_land_price.columns[shiga_land_price.columns.str.endswith("価格")]
Index(['S58価格', 'S59価格', 'S60価格', 'S61価格', 'S62価格', 'S63価格', 'H1価格', 'H2価格',
'H3価格', 'H4価格', 'H5価格', 'H6価格', 'H7価格', 'H8価格', 'H9価格', 'H10価格',
'H11価格', 'H12価格', 'H13価格', 'H14価格', 'H15価格', 'H16価格', 'H17価格', 'H18価格',
'H19価格', 'H20価格', 'H21価格', 'H22価格', 'H23価格', 'H24価格', 'H25価格', 'H26価格',
'H27価格', 'H28価格', 'H29価格', 'H30価格', 'H31価格', 'R2価格', 'R3価格', 'R4価格'],
dtype='object')
shiga_land_price_split = shiga_land_price.iloc[
:, : shiga_land_price.columns.get_loc("属性移動S59")
]
columns = list(shiga_land_price_split.columns)
columns[
shiga_land_price_split.columns.get_loc(
"S58価格"
) : shiga_land_price_split.columns.get_loc("R4価格")
+ 1
] = list(range(1983, 2023))
shiga_land_price_split.columns = columns
shiga_land_price_melt = pd.melt(
shiga_land_price_split,
id_vars=shiga_land_price.columns[: shiga_land_price_split.columns.get_loc(1983)],
value_vars=list(range(1983, 2023)),
var_name="年度",
value_name="価格",
)
shiga_land_price_melt.iloc[:5, -5:]
| 共通地点区分 | 対前年変動率 | 選定年次ビット | 年度 | 価格 | |
|---|---|---|---|---|---|
| 0 | False | 0.0 | 0000000000000000000000000000001111111111 | 1983 | 0 |
| 1 | False | 0.6 | 1111111111111111111111111111111111111111 | 1983 | 91800 |
| 2 | False | -0.5 | 1111111111111111111111111111111111111111 | 1983 | 65900 |
| 3 | True | -1.3 | 1111111111111111111111111111111111111111 | 1983 | 85500 |
| 4 | False | -2.9 | 0000000000000000001111111111111111111111 | 1983 | 0 |
px.scatter_mapbox(
shiga_land_price_melt,
lat="緯度",
lon="経度",
size="価格",
color="用途区分",
hover_name="市区町村名",
hover_data=["所在並びに地番"],
animation_frame="年度",
center={"lat": 35.09, "lon": 136.18},
opacity=0.5,
width=800,
height=800,
mapbox_style="carto-positron",
).show()