Loading [MathJax]/jax/output/HTML-CSS/config.js

[SciPy] 21. spatialのVoronoi,voronoi_plot_2dで塗りつぶしボロノイ図

matplotlib

はじめに

scipyのVoronoi,voronoi_plot_2dを使って、ボロノイ領域を塗りつぶしたボロノイ図を表示する方法について説明する。

コード&解説

モジュールのインポート

%matplotlib widget
import matplotlib.pyplot as plt
import numpy as np
from scipy.spatial import Voronoi, voronoi_plot_2d
from cycler import cycler

バージョン

#version
import matplotlib
import scipy
print(np.__version__)
print(matplotlib.__version__)
print(scipy.__version__)
1.21.3
3.4.3
1.7.1

デフォルトのカラーサイクルの変更

plt.rcParams['axes.prop_cycle']=cycler(color=plt.get_cmap("Set3").colors)

デフォルトの”tab10″から”Set3″にカラーサイクルを変更する。

データの作成

#make data
u=np.linspace(0,2*np.pi,9)
x=np.cos(u)
y=np.sin(u)
x2=3*np.cos(u)
y2=3*np.sin(u)

半径の異なる円状のデータを作成する。図で表示すると以下のようになる。

fig,ax=plt.subplots(figsize=(6,4),dpi=130)
ax.plot(x,y,"C2o")
ax.plot(x2,y2,"C3o")
ax.set_aspect(1)
plt.savefig("voronoi_fill_plot_2d_1.png",dpi=130)
plt.show()

ボロノイ図の作成

#Voronoi
arr1 = np.vstack((x,y))
arr2 = np.vstack((x2,y2))
points = np.hstack((arr1,arr2)).T
vor = Voronoi(points)

配列を結合して、Voronoiでボロノイ図を表示するためのデータを作成する。

ボロノイ図の表示

#show Voronoi
fig,ax=plt.subplots(figsize=(6,4),dpi=130)
voronoi_plot_2d(vor,line_colors='pink',ax=ax,line_width=2)
ax.set_aspect(1)
plt.savefig("voronoi_fill_plot_2d_2.png",dpi=130)
plt.show()

ボロノイ図はvoronoi_plot_2dで表示できる。voronoi_plot_2dについては、下記記事で解説した。

[SciPy] 10. voronoi_plot_2dによるボロノイ図の作成
ボロノイ図とは、任意の位置に配置された複数個の点に対して、同一平面上の他の点がどの点に近いかによって分割した図のことである。ここでは、scipy.spatialのVoronoi, voronoi_plot_2dでボロノイ図を作成する方法を紹介する。

ボロノイ図は下図のようになる。

塗りつぶしボロノイ図の表示

#show fill voronoi
fig,ax=plt.subplots(figsize=(6,4),dpi=130)
vor2d = voronoi_plot_2d(vor,line_colors='pink',ax=ax,line_width=2,show_vertices=True,show_points=True)
ax.set_aspect(1)
for region in vor.regions:
if -1 not in region:
ax.fill(vor.vertices[region][:, 0],
vor.vertices[region][:, 1])
plt.savefig("voronoi_fill_plot_2d_3.png",dpi=130)
plt.show()

vor.regionsで各ボロノイ領域を形成するボロノイ頂点のインデックスを取得し、vor.vertices[region]で塗りつぶす領域を決めて、塗りつぶす。vor.regionsに-1がある場合は、ボロノイ図の外側に頂点があることを意味するので、if -1 not in region:で塗りつぶさないようにする。

ランダムデータの場合

## random data
points = np.random.randn(100,2) #random points
vor = Voronoi(points)
fig,ax=plt.subplots(figsize=(6,4),dpi=130)
vor2d = voronoi_plot_2d(vor,line_colors='pink',ax=ax,line_width=2,show_vertices=False,show_points=False)
ax.set_aspect(1)
#ax.axis("off")
ax.set(xlim=(-1,1),ylim=(-1,1))
for region in vor.regions:
if -1 not in region:
ax.fill(vor.vertices[region][:, 0],
vor.vertices[region][:, 1])
plt.savefig("voronoi_fill_plot_2d_4.png",dpi=130)
plt.show()
コードをダウンロード(.pyファイル)

コードをダウンロード(.ipynbファイル)

参考

ボロノイ図 - Wikipedia
Voronoi — SciPy v1.15.2 Manual
voronoi_plot_2d — SciPy v1.15.2 Manual

コメント