Pythonの地図可視化ライブラリfoliumでインタラクティブな地図を作成してみる

Pythonの地図可視化ライブラリfoliumでインタラクティブな地図を作成してみる

2026.02.16

はじめに

データアナリティクス事業本部のkobayashiです。

Pythonでデータ分析を行っていると、位置情報や地理データを地図上に可視化したいケースがあるかと思います。matplotlibやplotlyでも地図の描画は可能ですが、インタラクティブな操作(ズーム、ドラッグ、クリックでの情報表示)を手軽に実現したい場合には少し手間がかかります。
今回は、PythonからインタラクティブなWebベースの地図を簡単に作成できるライブラリfoliumを試してみたのでその内容をまとめます。

foliumとは

foliumは、Pythonのデータ処理能力とJavaScriptの地図ライブラリであるLeaflet.jsのマッピング機能を組み合わせた地図可視化ライブラリです。Pythonで記述したコードから、ブラウザで閲覧できるインタラクティブな地図をHTMLファイルとして出力できます。

主な特徴としては以下になります。

  • Leaflet.jsをベースにしたインタラクティブな地図をPythonから生成できる
  • 出力はスタンドアロンのHTMLファイルのため、特別なサーバーなしにブラウザで閲覧可能
  • Jupyter Notebookとの親和性が高く、ノートブック上にインラインで地図を表示できる
  • GeoJSON/TopoJSONなどの地理データフォーマットを直接扱える
  • PandasやGeoPandasとの連携が容易
  • HeatMap、MarkerCluster、Choroplethなど40以上のプラグインが利用可能

環境

今回使用した環境は以下の通りです。

Python 3.12.8
folium 0.19.5
pandas 2.2.3

foliumを使ってみる

インストール

uvで簡単にインストールできます。

$ uv add folium

基本的な地図の作成

まずは最もシンプルな地図を作成してみます。folium.Map()に中心座標とズームレベルを指定するだけで地図が生成できます。

basic_map.py
import folium

# 東京駅を中心とした地図を作成
m = folium.Map(location=[35.6812, 139.7671], zoom_start=14)

# HTMLファイルとして保存
m.save("basic_map.html")

locationに緯度・経度のリスト、zoom_startに初期ズームレベルを指定します。save()でHTMLファイルとして出力され、ブラウザで開くとOpenStreetMapベースのインタラクティブな地図が表示されます。

basic_map

マーカーの追加

地図上にマーカーを追加してみます。folium.Marker()でマーカーを作成し、add_to()で地図に追加します。

marker_map.py
import folium

m = folium.Map(location=[35.6812, 139.7671], zoom_start=14)

# マーカーを追加
folium.Marker(
    location=[35.6812, 139.7671],
    popup="東京駅",
    tooltip="クリックで詳細表示",
).add_to(m)

# アイコンをカスタマイズしたマーカー
folium.Marker(
    location=[35.6586, 139.7454],
    popup="東京タワー",
    tooltip="東京タワー",
    icon=folium.Icon(color="red", icon="info-sign"),
).add_to(m)

m.save("marker_map.html")

popupはマーカーをクリックした際に表示される内容、tooltipはマウスホバー時に表示される内容になります。iconパラメータでマーカーの見た目をカスタマイズすることもできます。使用できるアイコンはBootstrap Glyphiconsになります。

marker_map

タイルレイヤーの変更

デフォルトではOpenStreetMapが使用されますが、tilesパラメータで背景地図を変更できます。

tile_map.py
import folium

# CartoDB positronタイルを使用(シンプルな淡色地図)
m = folium.Map(
    location=[35.6812, 139.7671],
    zoom_start=12,
    tiles="CartoDB positron",
)

m.save("tile_map.html")

利用可能なタイルとしてはOpenStreetMap(デフォルト)、CartoDB positronCartoDB dark_matterなどがあります。
tile_map

複数のレイヤーとレイヤーコントロール

複数のタイルレイヤーやマーカーグループを切り替えて表示する機能も用意されています。

layer_control_map.py
import folium

m = folium.Map(location=[35.6812, 139.7671], zoom_start=13)

# タイルレイヤーを追加
folium.TileLayer("CartoDB positron", name="CartoDB positron").add_to(m)
folium.TileLayer("CartoDB dark_matter", name="CartoDB dark_matter").add_to(m)

# レイヤーコントロールを追加
folium.LayerControl().add_to(m)

m.save("layer_control_map.html")

folium.LayerControl()を追加すると、地図の右上にレイヤー切り替えのUIが表示されます。

layer_control_map

図形の描画

マーカー以外にも、円やポリゴンなどの図形を地図上に描画できます。

shapes_map.py
import folium

m = folium.Map(location=[35.6812, 139.7671], zoom_start=13)

# 円を描画(半径はメートル単位)
folium.Circle(
    location=[35.6812, 139.7671],
    radius=500,
    color="blue",
    fill=True,
    fill_opacity=0.2,
    popup="東京駅から半径500m",
).add_to(m)

# ポリラインを描画
folium.PolyLine(
    locations=[
        [35.6812, 139.7671],
        [35.6586, 139.7454],
        [35.6762, 139.6503],
    ],
    color="red",
    weight=3,
    popup="東京駅→東京タワー→渋谷駅",
).add_to(m)

m.save("shapes_map.html")

Circleで円、PolyLineで折れ線、他にもPolygonで多角形、Rectangleで長方形の描画が可能です。なお、Circleはメートル単位の半径でズームレベルに応じてサイズが変化しますが、CircleMarkerはピクセル単位でズームに関係なく一定のサイズで表示されます。

shapes_map

応用的な使い方

GeoJSONデータの表示

foliumでは、GeoJSONフォーマットのデータを地図上にレイヤーとして表示できます。都道府県境界のGeoJSONデータは国土数値情報ダウンロードサービス等から入手できます。

geojson_map.py
import folium

m = folium.Map(location=[36.0, 138.0], zoom_start=5)

# GeoJSONデータを読み込んで表示
folium.GeoJson(
    "japan_prefectures.geojson",
    name="都道府県境界",
    style_function=lambda feature: {
        "fillColor": "#3186cc",
        "color": "black",
        "weight": 1,
        "fillOpacity": 0.3,
    },
).add_to(m)

folium.LayerControl().add_to(m)
m.save("geojson_map.html")

style_functionで各フィーチャーのスタイルをカスタマイズできます。GeoJSONファイルのパスやURLを直接指定でき、Pythonの辞書形式のGeoJSONデータも受け付けます。

geojson_map

コロプレスマップ(Choropleth Map)

コロプレスマップは、地域ごとの統計データを色の濃淡で可視化する手法です。foliumではChoroplethクラスを使うことでPandasのデータフレームとGeoJSONを紐付けて簡単に作成できます。

choropleth_map.py
import folium
import pandas as pd

# 都道府県別の人口データ(各都道府県の推計人口、2025〜2026年時点)
df = pd.DataFrame({
    "pref_code": [str(i) for i in range(1, 48)],
    "pref_name": [
        "北海道", "青森県", "岩手県", "宮城県", "秋田県", "山形県", "福島県",
        "茨城県", "栃木県", "群馬県", "埼玉県", "千葉県", "東京都", "神奈川県",
        "新潟県", "富山県", "石川県", "福井県", "山梨県", "長野県", "岐阜県",
        "静岡県", "愛知県", "三重県", "滋賀県", "京都府", "大阪府", "兵庫県",
        "奈良県", "和歌山県", "鳥取県", "島根県", "岡山県", "広島県", "山口県",
        "徳島県", "香川県", "愛媛県", "高知県", "福岡県", "佐賀県", "長崎県",
        "熊本県", "大分県", "宮崎県", "鹿児島県", "沖縄県",
    ],
    "population": [
        4997061, 1143112, 1123291, 2227328,  875323,  991279, 1712635,
        2788459, 1865615, 1872845, 7320901, 6275934, 14270748, 9217647,
        2066377,  983883, 1088470,  730468,  782503, 1969278, 1897676,
        3485908, 7450302, 1695415, 1395819, 2503355, 8773375, 5301987,
        1272220,  865884,  523208,  631514, 1812221, 2692560, 1258038,
         676246,  908642, 1255296,  643009, 5088814,  780313, 1232820,
        1680826, 1072468, 1015220, 1511919, 1468039,
    ],
})

m = folium.Map(location=[39.0, 140.0], zoom_start=6)

folium.Choropleth(
    geo_data="japan_prefectures.geojson",
    data=df,
    columns=["pref_code", "population"],
    key_on="feature.properties.id",
    fill_color="YlOrRd",
    fill_opacity=0.7,
    line_opacity=0.2,
    legend_name="人口",
).add_to(m)

m.save("choropleth_map.html")

geo_dataにGeoJSONのパス、dataにPandasのデータフレーム、columnsにキーカラムと値カラムを指定し、key_onでGeoJSONのプロパティとデータフレームのキーを紐付けます。fill_colorにはカラーパレット(YlOrRdBuGnPuRdなど)を指定できます。

なお、key_onで参照するGeoJSONのプロパティ値とcolumnsで指定するキー列の値は、型(文字列/数値)やゼロ埋め等の表記が完全に一致している必要があります。一致しない場合、色が塗られない領域が発生するので注意してください。

choropleth_map

ヒートマップ

folium.pluginsにはヒートマップなどの便利なプラグインが含まれています。

heatmap.py
import folium
from folium.plugins import HeatMap

m = folium.Map(location=[35.6812, 139.7671], zoom_start=12)

# ヒートマップ用のデータ(緯度, 経度, 重み)
heat_data = [
    [35.6812, 139.7671, 1.0],
    [35.6586, 139.7454, 0.8],
    [35.6762, 139.6503, 0.9],
    [35.6895, 139.6917, 0.7],
    [35.7100, 139.8107, 0.6],
    [35.6938, 139.7035, 0.85],
]

HeatMap(heat_data, radius=30).add_to(m)

m.save("heatmap.html")

HeatMapに緯度・経度(とオプションで重み)のリストを渡すだけでヒートマップが生成できます。radiusでヒートマップの各ポイントの半径を調整できます。

heatmap

MarkerCluster

大量のマーカーを表示する場合、MarkerClusterプラグインを使うとズームレベルに応じてマーカーを自動的にクラスタリングしてくれます。

marker_cluster.py
import folium
from folium.plugins import MarkerCluster

m = folium.Map(location=[35.6812, 139.7671], zoom_start=12)

marker_cluster = MarkerCluster().add_to(m)

# 複数のマーカーをクラスターに追加
locations = [
    ([35.6812, 139.7671], "東京駅"),
    ([35.6586, 139.7454], "東京タワー"),
    ([35.6762, 139.6503], "渋谷駅"),
    ([35.6895, 139.6917], "新宿駅"),
    ([35.7100, 139.8107], "東京スカイツリー"),
    ([35.6938, 139.7035], "六本木ヒルズ"),
    ([35.7148, 139.7967], "浅草寺"),
    ([35.6596, 139.7006], "恵比寿ガーデンプレイス"),
    ([35.6764, 139.6993], "明治神宮"),
    ([35.6852, 139.7528], "皇居"),
    ([35.6595, 139.7005], "目黒川"),
    ([35.7146, 139.7732], "上野恩賜公園"),
    ([35.7156, 139.7745], "国立西洋美術館"),
    ([35.7196, 139.7726], "東京国立博物館"),
    ([35.6654, 139.7707], "築地本願寺"),
    ([35.6605, 139.7292], "国立新美術館"),
    ([35.6329, 139.8804], "東京ディズニーランド"),
    ([35.6267, 139.7741], "お台場海浜公園"),
    ([35.6197, 139.7771], "フジテレビ本社"),
    ([35.6684, 139.6013], "井の頭恩賜公園"),
    ([35.7023, 139.5745], "三鷹の森ジブリ美術館"),
    ([35.6994, 139.7745], "秋葉原"),
    ([35.6702, 139.7721], "銀座四丁目交差点"),
    ([35.6110, 139.7163], "等々力渓谷"),
    ([35.7281, 139.7187], "サンシャイン60展望台"),
    ([35.6580, 139.7016], "代官山T-SITE"),
    ([35.6715, 139.7653], "歌舞伎座"),
    ([35.6897, 139.7005], "東京都庁展望室"),
]

for loc, name in locations:
    folium.Marker(location=loc, popup=name, tooltip=name).add_to(marker_cluster)

m.save("marker_cluster_map.html")

マーカーをMarkerClusterオブジェクトに追加することで、ズームアウト時にはクラスターとしてまとまり、ズームインすると個々のマーカーが表示されます。大量のマーカーを表示する際にブラウザのパフォーマンスを維持するためにも有効です。

marker_cluster_optimized

MiniMap

地図の隅に全体俯瞰用の小さな地図を表示するMiniMapプラグインもあります。

minimap.py
import folium
from folium.plugins import MiniMap

m = folium.Map(location=[35.6812, 139.7671], zoom_start=14)

MiniMap().add_to(m)

m.save("minimap_map.html")

MiniMap()を追加するだけで、地図の右下に現在の表示範囲を示す小さな地図が表示されます。

minimap

まとめ

Pythonの地図可視化ライブラリfoliumを使ってインタラクティブな地図を作成してみました。folium.Map()で地図を作成し、マーカーや図形をadd_to()で追加していくというシンプルなAPIで、HTMLファイルとして手軽に出力できるのが便利だと感じました。また、HeatMapやMarkerCluster、Choroplethなどのプラグインも充実しており、データ分析で位置情報を扱う際の可視化ツールとして活用できそうです。

最後まで読んで頂いてありがとうございました。

この記事をシェアする

FacebookHatena blogX

関連記事