Open In Colab

地理データの可視化#

本節では緯度・経度の情報をもつ、地理データを可視化する手法を学びます。

国土交通省の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.style

https://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()