Quantcast
Channel: pandas - よちよちpython
Viewing all articles
Browse latest Browse all 30

【folium】複数の座標から中心座標を算出して地図を作成する

$
0
0

今回は、地図作成ライブラリfoliumで複数地点の中心座標を算出する方法をやります。

f:id:chayarokurokuro:20210730092759j:plain



参考リンク

  • foliumオフィシャル

folium — Folium 0.12.1 documentation


plugins — Folium 0.12.1 documentation



foliumでは最初にマップオブジェクトを作成する際、中心座標を与えなければなりません。できた地図にマーカーなどを載せていきデコレートしたりしていきますが、複数のマーカーの座標から中心座標が求められれば、地図の中心が点在するマーカーのちょうど真ん中になり見やすくなるはずです。



【実行環境】

  • Android
  • Termux
  • Python 3.9.6
  • Jupyter Notebook
  • 使用するライブラリ
    • Pandas1.2.5、Numpy1.12.1、folium0.12.1



目次



座標のデータを用意し、地図を作りながら見ていきます。



マーカー用の座標データ

import pandas as pd

# 座標(緯度・経度)のデータ
fname = 'latlng_list.csv'
# CSVファイル読み込み
df = pd.read_csv(fname, header=None)
df = df.rename(columns={0:"地名" ,1:"緯度", 2:"経度"})

# 絞り込み
latlng_df = df.iloc[34:36, :]

# 表示
latlng_df
地名緯度経度
34平城京34.690710135.794281
35平安京35.011005135.759831

このような座標データがあります。この2点にマーカーを差します。



複数の座標から中心座標を算出する

2ヶ所の中心座標を求めたいので、緯度と経度のそれぞれで平均値を出します。

Pandasで平均値を出すにはmean()を使うと簡単に出来ます。列で平均値を出したいので、引数にaxis=0を指定する。

# dfの列で平均値を算出
mean_data = latlng_df.mean(axis=0)

# 表示print(type(mean_data))
mean_data
<class 'pandas.core.series.Series'>





緯度     34.850858
経度    135.777056
dtype: float64

2点の中心座標がSeriesで作られました。



地図作成

まずは基本となる地図を作ります。

# 地図オブジェクト作成import folium
from folium import plugins

m = folium.Map(mean_data)

# 表示
m
Make this Notebook Trusted to load map: File -> Trust Notebook

座標はSeries型でも大丈夫のようです。(あとにあるように、マーカーを差す時はSeriesは使えない。)

zoom_startは指定しませんでしたのでデフォルト値の10です。

これでは中心がどこなのかわかりませんので、次はマーカーを差します。

# 中心座標にマーカーを追加
folium.Marker(
    location = mean_data,
    popup = "center"
).add_to(m)

# 追加後の地図表示
m
---------------------------------------------------------------------------

ValueError                                Traceback (most recent call last)

/data/data/com.termux/files/usr/tmp/ipykernel_24080/4033970411.py in <module>
      1 # 中心座標にマーカーを追加
----> 2 folium.Marker(
      3     location = mean_data,
      4     popup = "center"
      5 ).add_to(m)


/data/data/com.termux/files/usr/lib/python3.9/site-packages/folium/map.py in __init__(self, location, popup, tooltip, icon, draggable, **kwargs)
    275         super(Marker, self).__init__()
    276         self._name = 'Marker'
--> 277         self.location = validate_location(location) if location else None

(中略)

ValueError: The truth value of a Series is ambiguous. Use a.empty, a.bool(), a.item(), a.any() or a.all().

あら? マーカーの座標ではSeriesはでけまへんがなと怒られた。ならば、リストに変換する。

# 中心座標にマーカーを追加
folium.Marker(
    location = mean_data.tolist(),
    popup = "center"
).add_to(m)

# 追加後の地図表示
m
Make this Notebook Trusted to load map: File -> Trust Notebook

OK牧場

したらば、次は平城京平安京にマーカーを差します。何か変わったアイコンを差してみましょうかね!

# 平城京に差す
folium.Marker(
    location = latlng_df.iloc[0, 1:3].tolist(),
    icon = plugins.BeautifyIcon(border_color='#00ea47',
                               text_color='#03ff04',
                               number=1,
                               inner_icon_style='margin-top:0;')

).add_to(m)
<folium.map.Marker at 0x73f87eaa90>
# 平安京に差す
folium.Marker(
    location = latlng_df.iloc[1, 1:3].tolist(),
    icon = plugins.BeautifyIcon(border_color='#e00e19',
                               text_color='#ff5204',
                               number=2,
                               inner_icon_style='plane')

).add_to(m)
<folium.map.Marker at 0x73f88b6d60>
# 地図表示
m
Make this Notebook Trusted to load map: File -> Trust Notebook

中心座標は真ん中に来ているようですね。

もう少し座標を増やして中心を決定する

新規に地図を作成します。マーカーの座標を増やして今までと同じことをやります。

# 座標データの用意
loc_df = df.query('地名 == ["山形駅","新鹿児島駅","高松駅","岩手駅"]')
# 表示
loc_df
地名緯度経度
37山形駅38.248926140.327303
39岩手駅39.701437141.136723
41新鹿児島駅31.583785130.541245
44高松駅34.350680134.046928

この4点の中心座標を算出し、地図のベースを作成します。
そこにマーカーを差します。

# 中心座標の算出
center = loc_df.mean(axis=0).tolist()

# 地図を作成map = folium.Map(
    location = center,
    zoom_start = 3
)


# 地図の中心座標に赤色のマーカーを差す

folium.Marker(
    location = center,
    popup = "中心点",
    icon = folium.Icon(color="red")
).add_to(map)


# 他の4点のマーカーを緑で差す# 4点の座標配列
latlngs = loc_df.iloc[:,1:3].values.tolist()

# 4点の地名配列(popup用)
names = loc_df['地名'].values.tolist()

# 4点のマーカーを差すfor latlng, name inzip(latlngs, names):
    folium.Marker(
        location = latlng,
        popup = name,
        icon = folium.Icon(color="green")
    ).add_to(map)
    
# 表示map
Make this Notebook Trusted to load map: File -> Trust Notebook

できた。

folium.Marker()で使うマーカーの座標はDataFrame型やSeries型ではエラーが出る。よってリストに変換しているが、データフレーム型をリストにするにも一旦valuesto_numpy()を使ってデータの中身だけにしたあとtolist()で変換させた。いきなりtolist()だとエラー。

zoom_startの値もマーカーの座標の散らばり具合で自動的に変更できるようにすれば良くなると思うが、座標とzoom_startの表示範囲の関係がわからない。

最後にもう1つ。

地名緯度経度
134福岡県庁33.606314130.418029
135佐賀県33.249439130.298804
136大分県33.238200131.612674
137長崎県32.750336129.867908
138熊本県32.789826130.741478
139宮崎県庁31.910908131.423898
140鹿児島県庁31.560183130.557968
141沖縄県26.212523127.680771



Make this Notebook Trusted to load map: File -> Trust Notebook



赤色のマーカーが中心に来ているかな? 沖縄が遠すぎる気が…



  • 参考リンク

【folium】地図のMarkerの色や形・アイコン・タイルを変える - よちよちpython



今回は以上です。


Viewing all articles
Browse latest Browse all 30

Trending Articles