ダムの貯水量を地図上に可視化

前処理

[1]:
import geopandas as gpd
import numpy as np
import pandas as pd
import plotly.express as px
import plotly.graph_objects as go

import mapbox_env

データをpandas.DataFrameに読み込み

[2]:
df = gpd.read_file("data/dam.geojson")
df.head()
[2]:
W01_001 W01_002 W01_003 W01_004 W01_005 W01_006 W01_007 W01_008 W01_009 W01_010 W01_011 W01_012 W01_013 W01_014 geometry
0 駒込 191 堤川 駒込川 7 1,2,6 84.5 270.0 320 7800 4 - 青森県青森市大字駒込 4 POINT (140.88589 40.70977)
1 下湯 192 堤川 堤川 12 1,2,4 70.0 783.5 3723 12600 4 1988 青森県青森市大字荒川字横倉 1 POINT (140.77942 40.69178)
2 浅虫 193 浅虫川 浅虫川 7 1,2 9.0 215.0 10 300 4 2002 青森県青森市大字浅虫字山下 1 POINT (140.87188 40.88522)
3 田の沢溜池 194 小湊川 小湊川 3 3 21.0 205.0 124 1174 5 1945 青森県東津軽郡平内町大字松野木 1 POINT (140.99147 40.89848)
4 清水目 195 野辺地川 野辺地川 7 1 33.5 195.0 75 2630 4 2000 青森県上北郡東北町字清水目 1 POINT (141.07611 40.81095)

緯度経度のデータを取得

[3]:
df[["lon", "lat"]] = pd.DataFrame(
    df["geometry"].map(lambda d: (d.x, d.y)).values.tolist()
)
df[["lon", "lat"]].head()
[3]:
lon lat
0 140.885894 40.709771
1 140.779421 40.691777
2 140.871879 40.885218
3 140.991475 40.898485
4 141.076114 40.810955

データのクリーニング

[4]:
def clean_data(data, data_type, cond):
    try:
        ret = data_type(data)
    except Exception:
        ret = np.nan
    if not cond(ret):
        ret = np.nan
    return ret

for col in "W01_007", "W01_008", "W01_009", "W01_010", "W01_012":
    df[col] = df[col].map(lambda x: clean_data(x, np.float, lambda x: x > 0))

形式を文字列に変換

[5]:
dam_type_dict = {
    "1": "アーチダム",
    "2": "バットレスダム",
    "3": "アースダム",
    "4": "アスファルトフェイシングダム",
    "5": "アスファルトコアダム",
    "6": "フローティングゲートダム(可動堰)",
    "7": "重力式コンクリートダム",
    "8": "重力式アーチダム",
    "9": "重力式コンクリートダム・フィルダム複合ダム",
    "10": "中空重力式コンクリートダム",
    "11": "マルティプルアーチダム",
    "12": "ロックフィルダム",
    "13": "台形CSGダム",
}
df["W01_005"] = df["W01_005"].map(dam_type_dict)

欠損値を除外

[6]:
df.dropna(inplace=True)

地図上に可視化

plotly.pyで可視化

[10]:
mapbox_token = mapbox_env.token
fig = go.Figure(
    go.Scattermapbox(
        lon=df["lon"].values,
        lat=df["lat"].values,
        text=df["W01_001"],
        hovertemplate="%{text}<br>lon: %{lon:.2f}, lat: %{lat:.2f}",
        opacity=0.3,
        marker={"size": df["W01_010"] * 1e-4, "color": df["W01_007"]},
    ),
    layout={
        "width": 800,
        "height": 700,
        "mapbox": go.layout.Mapbox(
            accesstoken=mapbox_token, center={"lat": 38, "lon": 138}, zoom=4
        ),
    },
)
fig.show()

Plotly Expressで可視化

[11]:
px.set_mapbox_access_token(mapbox_token)
px.scatter_mapbox(
    df,
    lat="lat",
    lon="lon",
    size=df["W01_010"] * 1e-3,
    color="W01_007",
    text="W01_005",
    animation_frame=df["W01_012"].sort_values(),
    zoom=4,
    width=900, height=800,
    opacity=0.3,
).show()