Pythonでボロノイ図の作成

～これまでのロードマップ～

某東京都カーディーラーの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が入ります。
```python
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')
```
![スクリーンショット 2023-11-11 115748.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3615177/8f56c82e-fb19-cc4e-37fd-0347aa4e7613.png)