0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

streamlitで位置情報をプロットするマップを比較する

Posted at

はじめに

streamlitで位置情報をプロットする際、地図上に線や点を打てる状態にしたい。
そこで、streamlitで実装可能なOpenStreatMapCartoDBについて比較してみる。

比較

観点 OpenStreetMap CartoDB Positron CartoDB DarkMatter グラフ表示
コード量 ✅ 短い ✅ 短い ✅ 短い ❌ やや多い
点の見やすさ ❌ 見ずらい ✅ 見やすい ✅ 見やすい ✅ 見やすい
距離感の表現 ✅ 見やすい ✅ 見やすい ✅ 見やすい ❌ 分かりずらい
おすすめ度 周辺の道路情報などを合わせて利用したい場合 シンプル一番おすすめ ダークテーマに対応させる場合 位置関係の形だけ見たいとき

それぞれのグラフは、fig.update_layoutmap_styleで名称を指定することで切り替えられる。

# 地図表示
def create_map(style_name: str):
    fig = px.scatter_map(
        df,
        lat="lat",
        lon="lon",
        hover_name="place",
        zoom=zoom,
        height=height,
    )
    fig.update_traces(marker=dict(size=point_size))
    fig.update_layout(
        map_style=style_name,
        margin=dict(l=0, r=0, t=30, b=0),
    )
    return fig

OpenStreatMap

実際の街の雰囲気が一番わかりやすい標準マップ。
点の位置を現実の地形と結びつけたい時に便利。
image.png

CartoDB Positron

背景が控えめで情報が整理され、点やラベルがとても見やすい。可視化用途では一番使うことになると思う。
image.png

CartoDB DarkMatter

ダークテーマ版。もし、streamlit全体のテーマをダークテーマで作るならこっち。
image.png

(参考)グラフにプロットすると

純粋に位置関係の“形”だけを見るときに使う。位置情報というより分布などをのみに絞ってみたいときであれば一度こっちでプロットするかもしれない。
image.png

コード全文

import streamlit as st
import pandas as pd
import plotly.express as px
import plotly.graph_objects as go

st.set_page_config(page_title="Plotly Map 比較", layout="wide")

# サンプルとなるデータ
df = pd.DataFrame({
    "lat": [35.681236, 35.689487, 35.658034],
    "lon": [139.767125, 139.691711, 139.701636],
    "place": ["東京駅", "新宿駅", "渋谷駅"],
})

# サイドバー設定値
st.sidebar.header("表示設定")
zoom = st.sidebar.slider("ズーム", 10, 16, 12)
height = st.sidebar.slider("高さ(px)", 300, 800, 500)
point_size = st.sidebar.slider("点サイズ", 5, 30, 15)

# 比較対象
TILES = {
    "OpenStreetMap": "open-street-map",
    "CartoDB Positron": "carto-positron",
    "CartoDB DarkMatter": "carto-darkmatter",
    "グラフ表示": "white-plot",
}
tabs = st.tabs(list(TILES.keys()))

# 地図表示
def create_map(style_name: str):
    fig = px.scatter_map(
        df,
        lat="lat",
        lon="lon",
        hover_name="place",
        zoom=zoom,
        height=height,
    )
    fig.update_traces(marker=dict(size=point_size))
    fig.update_layout(
        map_style=style_name,
        margin=dict(l=0, r=0, t=30, b=0),
    )
    return fig

# グラフ表示
def create_white_plot():
    fig = go.Figure()

    # 散布図(XY)
    fig.add_trace(
        go.Scatter(
            x=df["lon"],
            y=df["lat"],
            mode="markers+text",
            text=df["place"],
            textposition="top center",
            marker=dict(size=point_size, color="red"),
        )
    )

    # レイアウト(xaxis / yaxis を1回だけ定義)
    fig.update_layout(
        title="白背景 XY グラフ(グリッドなし)",
        xaxis=dict(
            title="Longitude (°)",
            showgrid=False,
        ),
        yaxis=dict(
            title="Latitude (°)",
            scaleanchor="x",   # X軸と比率固定
            scaleratio=1,
            showgrid=False,
        ),
        height=height,
        margin=dict(l=0, r=0, t=30, b=0),
        plot_bgcolor="white",
    )

    return fig

# タブ表示
for tab, (label, style_name) in zip(tabs, TILES.items()):
    with tab:
        st.subheader(label)

        if style_name == "white-plot":
            st.write("地図ではなく、緯度・経度をXY軸にした **Plotlyグラフ** を表示しています。")
            fig = create_white_plot()
            st.plotly_chart(fig, width="stretch")
        else:
            fig = create_map(style_name)
            st.plotly_chart(fig, width="stretch")

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?