位置情報 Web アプリを作成する最も簡単な方法 (2021年)


Location Tech Advent Calendar 2021 by LBMA Japan 23日目の投稿です。

皆さん、こんにちは。株式会社 unerry で位置情報データの解析やデータ基盤の整備を担当している浅井と申します。

この記事では、Python の [streamlit](https://streamlit.io/) ライブラリを利用して、とても少ないコード量で簡単に位置情報データを地図上に表示する Web アプリを作成する方法を紹介いたします。位置情報の可視化の方法には様々な手法がありますが、Python プログラマーとって、2021年末時点で最も簡単な方法ではないかと思っています。

- [完成](https://share.streamlit.io/five-dots/streamlit_qiita/demo.py)
- [Github リポジトリ](https://github.com/five-dots/streamlit_qiita)

## 位置情報の可視化と共有

データ分析のサイクルにおいて、データを何らかの手法で可視化することの重要性は言うまでもないでしょう。チームメンバーと知見を共有する上でも、単に分析結果を共有するだけに比べて、可視化による説明を加えることで、良いフィードバックを得られることが格段に増えると感じます。

具体的な可視化手法として、一般的に使われていそうなものを挙げてみました。

1. Python/R などの可視化ライブラリを利用して静的なプロットを作成する
2. QGIS などの GIS アプリを利用する
3. Tableau などの BI ツールを利用する
4. Jupyter Notebook 内で、leaflet や kepler.gl を利用する
5. 専用の Web アプリを開発する

どれも扱うデータが位置情報となると、意外に面倒だったりしないでしょうか？ 特に地図上に表示する場合には、ベースとなるマップタイルの設定や、それを利用するための API の設定、CRSの理解や、インタラクティブな地図を作成するための JavaScript Library の習得など慣れていないと結構手間取ることが多いと感じています。(現に自分がそうでした。。。)

## streamlit の登場

上述の 1〜4 のような手法は、見る側に専用のアプリや環境を用意することができないことも多く、やはりブラウザだけで見られる 4 が理想と言えるのではと思います。そこで、登場するのが今回の主役の streamlit です。streamlit は、データ可視化に特化した Web Framework で、リリースは、2019年ととても若いプロジェクトですが、急激に人気を博してきているフレームワークです。

Python dash との Github Star 数の比較:
![streamlit_vs_dash.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/178795/2a635aed-cf13-1384-c054-625605183905.png)

## 環境

- Python 3.9.9
- streamlit 1.3.0
- pydeck 0.7.1

## インストール

インストールは pip 一撃です。依存関係として、今回のサンプルプログラムで必要な pandas, numpy, pydeck などもインストールされます。

```sh
pip install streamlit
```

正しくバージョン情報が出力されていれば、インストールは完了です。

```sh
streamlit --version
```

```text
Streamlit, version 1.3.0
```

## Mapbox API Token の設定

streamlit ではマップ表示のライブラリとして、[deck.gl](https://deck.gl/) を利用しています (実際には、その Python Wrapper の [pydeck](https://deckgl.readthedocs.io/en/latest/))。そして、その deck.gl がデフォルトのベースマップとして Mapbox を利用しているため、先ず [Mapbox](https://www.mapbox.com/) から API Key を取得し設定します。

設定ファイルは、グローバルに設定する場合は、`$HOME/.streamlit/config.toml`、プロジェクト単位に設定する場合は、プロジェクトルート配下の `./.streamlit/config.toml` です。

```toml:./.streamlit/config.toml
[mapbox]
token = "your api key"
```

## サンプルプログラム

ごく単純な例として、東京駅を中心に擬似的な位置情報データを生成して地図上にプロットするコードです。

```python:demo.py
import streamlit as st
import pandas as pd
import numpy as np

# 東京駅を中心に擬似的な位置情報データを生成する
lat, lon = 35.68184, 139.76718
df = pd.DataFrame(
    np.random.randn(1000, 2) / [100, 100] + [lat, lon],
    columns=['lat', 'lon']
)

st.title("位置情報 Web アプリを作成する最も簡単な方法")
st.subheader("Location Tech Advent Calendar 2021 by LBMA Japan")
st.map(df)
```

この Python スクリプトを引数に `streamlit run` を実行すると地図アプリケーションの完成です。わずか 15 行弱のコードでインタラクティブの地図上に自前のデータをプロットする Web アプリを作ることができました。

```sh
streamlit run demo.py
```

![screenshot.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/178795/418ff98f-977b-6819-6080-89af917d18bf.png)


今回は、手軽さを強調するため、最も簡便な `st.map` 関数のみを利用しました。`st.pydeck_chart` を利用すれば、[Layer Catalog Overview](https://deck.gl/docs/api-reference/layers) に記載されている複数のレイヤーを組合せて、より表現力の高いアプリを作成することも可能です。

また、今回は利用しませんでしたが、UI Widget も一通りのものが揃っており、ユーザーの入力に応じて地図の表示が動的に変わるようなアプリも簡単に実装できるでしょう。

## アプリ共有方法

作成したアプリは、[Streamlit Cloud](https://streamlit.io/cloud) を利用すると簡単に公開できます。Streamlit Cloud は Public App のみであれば無料で利用できる (Private App は 1つのみ) ため、記事冒頭のリンクは、Streamlit Cloud を使ってデプロイしたものです。

また、`streamlit run` はローカルの Python スクリプトだけでなく、URL を受け取ることも可能なため、Gist などでスクリプトを公開し、チームメンバー各自のローカルで streamlit を実行してもうらような使い方も可能です。

今回の例であれば、以下のコマンドでローカル実行が可能です。

```sh
streamlit run https://raw.githubusercontent.com/five-dots/streamlit_qiita/master/demo.py
```

## まとめ

streamlit は、データ分析や機械学習の成果を可視化・共有するための近年急成長中の Web フレームワークです。煩雑になりがちな地図上での位置情報の可視化も簡単なコードで実装し、すぐに公開することができるようになりました。今回作成したアプリ自体は意味のない簡易的なものですが、streamlit の手軽さは感じていただけたのではないかと思います。