Tak's Notebook

Kaggle, Machine Learning, Engineering

Folium での Mapbox tile の使い方

これは何か?

  • folium で Mapbox をベースタイルに使いたい
  • 公式ドキュメントのチュートリアルどおりにやってもエラーが出る
  • API をマニュアルで設定してあげると表示される

folium のバージョン

import folium
print(f"folium version: {folium.__version__}")
folium version: 0.10.0

Mapbox の設定

API KEYを取得

アカウント登録すると API Key を取得可能。個人的な利用なら無料でできそう(詳しくは料金表を参照)

https://account.mapbox.com

MAPBOX_API_KEY = YOUR_API_KEY

Mapbox Attribution

ビルドインのタイルの場合は attribution が用意されているが、 folium でカスタムタイルを使用するときは適当な attribution を自分で付ける必要がある。

Mapbox の場合は以下を参照する。

https://docs.mapbox.com/help/how-mapbox-works/attribution/#static--print

MAPBOX_ATTR = "© <a href='https://www.mapbox.com/about/maps/'>Mapbox</a> © <a href='http://www.openstreetmap.org/copyright'>OpenStreetMap</a> <strong><a href='https://www.mapbox.com/map-feedback/' target='_blank'>Improve this map</a></strong>"

Mapbox を folium のタイルに利用する

こちらを参考に

https://python-visualization.github.io/folium/quickstart.html

OpenStreetMap

デフォルトのタイルは OpenStreetMap

DEFAULT_LOCATION = [35.6812362, 139.7671248]
DEFAULT_ZOOM_START = 10
m = folium.Map(location=DEFAULT_LOCATION, zoom_start=DEFAULT_ZOOM_START)
m

f:id:takaishikawa42:20191111072031p:plain
OpenStreetMap

Mapbox

記述されている通りに Mapbox をタイルに指定する

m = folium.Map(
    location=DEFAULT_LOCATION,
    zoom_start=DEFAULT_ZOOM_START,
    tiles="Mapbox",
    API_key=MAPBOX_API_KEY,
)
m

なぜだか以下のエラーが出る。API_key を渡しているはずだが...。

ValueError: You must pass an API key if using Cloudmade or non-default Mapbox tiles.

解決策

マニュアルでAPIを指定してあげる

以下の Issue を参考にして解決できた。

https://github.com/python-visualization/folium/issues/922

m = folium.Map(
    location=DEFAULT_LOCATION,
    zoom_start=DEFAULT_ZOOM_START,
    tiles=f"https://api.mapbox.com/v4/mapbox.streets/{{z}}/{{x}}/{{y}}.png?access_token={MAPBOX_API_KEY}",
    attr=MAPBOX_ATTR,
)
m

f:id:takaishikawa42:20191111072134p:plain
Mapbox

Mapbox API のバージョンが folium パッケージでは v3 が使われている一方、2015年以降に新規登録したユーザーは v4 しか使えないことに起因しているっぽい。そのようなことが書いてあった。

Issue で議論されていることや Mapbox API ドキュメントの内容を正確に理解できていないので根本的な解決法なのかは不明だけど、暫定的にはこの方法で対応できた。