~これまでのロードマップ~
某東京都カーディーラーのWEBサイトをスクレイピング → GeoCodingで緯度・経度取得 → foliumでロケーションマップ作成 → 今回
【ボロノイ図の生成】
前回つくった東京都カーディーラーのロケーションマップに
scipy.spatial import Voronoiを使ってボロノイ図を追加していきます。
緯度・経度の入るcsvファイルをGoogleDriveに置き、Google Colaboratoryで実行しています。
SCVファイルのカラムはA列Shop Name{i}、B列Address、C列Latitude{i}、D列Longitude{i} ×10となっていて、{i}には1~10が入ります。
import pandas as pd
import folium
from scipy.spatial import Voronoi
import numpy as np
from chardet.universaldetector import UniversalDetector
csv_file_path = 'GoogleDriveのファイルパス'
detector = UniversalDetector()
with open(csv_file_path, 'rb') as file:
for line in file:
detector.feed(line)
if detector.done:
break
detector.close()
encoding = detector.result['encoding']
df = pd.read_csv(csv_file_path, encoding='shift_jis')
m = folium.Map(location=[df['Latitude1'].mean(), df['Longitude1'].mean()], zoom_start=10)
colors = ['green', 'blue', 'gray', 'red', 'purple', 'lightblue', 'pink', 'orange', 'lightgray', 'lightgreen']
for i in range(1, 11):
lat_col = f'Latitude{i}'
lon_col = f'Longitude{i}'
filtered_df = df.dropna(subset=[lat_col, lon_col])
for _, row in filtered_df.iterrows():
lat = row[lat_col]
lon = row[lon_col]
popup_text = row[f'Shop Name{i}']
icon_color = colors[(i - 1) % len(colors)]
folium.Marker(
[lat, lon],
tooltip=row[f'Address{i}'],
icon=folium.Icon(color=icon_color),
popup=popup_text
).add_to(m)
points = []
for i in range(1, 9):
lat_col = f'Latitude{i}'
lon_col = f'Longitude{i}'
filtered_df = df.dropna(subset=[lat_col, lon_col])
lat_lon = filtered_df[[lat_col, lon_col]].values
points.extend(lat_lon.tolist())
vor = Voronoi(points)
encoded_polygons = []
for region in vor.regions:
if not -1 in region and len(region) > 0:
polygon = [vor.vertices[i] for i in region]
encoded_polygons.append(polygon)
for region in encoded_polygons:
polygon = np.array(region)
folium.Polygon(
locations=polygon,
color='blue',
fill=True,
fill_color='blue',
fill_opacity=0.4
).add_to(m)
vor = Voronoi(points)
map_bounds = m.get_bounds()
map_width = map_bounds[1][1] - map_bounds[0][1]
map_height = map_bounds[1][0] - map_bounds[0][0]
filtered_edges = []
for edge in vor.ridge_vertices:
if -1 not in edge:
x0, y0 = vor.vertices[edge[0]]
x1, y1 = vor.vertices[edge[1]]
if (x0 >= map_bounds[0][1] and x0 <= map_bounds[1][1] and y0 >= map_bounds[0][0] and y0 <= map_bounds[1][0]) or (x1 >= map_bounds[0][1] and x1 <= map_bounds[1][1] and y1 >= map_bounds[0][0] and y1 <= map_bounds[1][0]):
filtered_edges.append(edge)
html = '<div style="position: absolute; left: 20px; top: -300px; white-space: nowrap; font-size: 15px; color: black;">GREEN=外車<br>BLUE=レクサス<br>GRAY=スバル<br>PURPLE=マツダ<br>LIGHTBLUE=スズキ<br>PINK=ダイハツ<br>ORANGE=トヨタ<br>RED=三菱<br>lightgray=ホンダ<br>lightgreen=日産</div>'
marker = folium.Marker(
[df['Latitude1'].mean(), df['Longitude1'].mean()],
icon=folium.DivIcon(html=html)
)
marker.add_to(m)
m.save('生成するファイル名.html')