質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.35%
Matplotlib

MatplotlibはPythonのおよび、NumPy用のグラフ描画ライブラリです。多くの場合、IPythonと連携して使われます。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

Q&A

解決済

1回答

2912閲覧

python,matplotlibにおけるボロノイ図の描画について

narimi

総合スコア18

Matplotlib

MatplotlibはPythonのおよび、NumPy用のグラフ描画ライブラリです。多くの場合、IPythonと連携して使われます。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

0グッド

0クリップ

投稿2021/12/20 11:07

特定の図形内に指定した点によるボロノイ図を作成したい

pythonのライブラリであるmatplotlibにて,ボロノイ図の描画を行おうと思っております.

用意している情報はポリゴンの座標リストとボロノイ図作成の際に必要な母点の座標リストです.

発生している問題・エラーメッセージ

shapely.errors.TopologicalError: The operation 'GEOSIntersection_r' could not be performed. Likely cause is invalidity of the geometry <shapely.geometry.polygon.Polygon object at 0x0000029A93E85940>

該当のソースコード

python

1from scipy.spatial import Delaunay, delaunay_plot_2d, Voronoi, voronoi_plot_2d 2import matplotlib.pyplot as plt 3import matplotlib.patches as patch 4from matplotlib.collections import PolyCollection 5from scipy.spatial import Voronoi, voronoi_plot_2d 6from shapely.geometry import Polygon 7import numpy as np 8import math 9 10data = np.array([[11.322,5.82], 11 [64.808,6.401], 12 [50.481,35.431], 13 [53.738,50.02], 14 [52.727,76.305], 15 [29.215,72.951], 16 [24.786,55.766], 17 [10.013,45.077] 18 ]) 19 20 pt = np.array([[15.22142778, 38.74503721], 21 [26.01477792, 38.86749356], 22 [30.86884446, 48.17364433], 23 [40.64079104, 61.38215327], 24 [36.53142362, 10.81861143], 25 [20.89040778, 19.60481585], 26 [52.0941051, 20.63233987], 27 [46.06085561, 70.15568748], 28 [31.48504392, 19.81353478], 29 [15.90721556, 10.57598896], 30 [26.01360206, 28.55506018], 31 [48.96167152, 55.27385493], 32 [41.17787351, 48.50723961], 33 [46.83406199, 11.28722635], 34 [33.1668619, 68.509277 ], 35 [57.14529894, 11.43505146], 36 [41.78480506, 20.3275005 ], 37 [30.74029729, 58.48498758], 38 [26.21789971, 10.77473159], 39 [46.62100914, 39.72495837], 40 [46.67382691, 29.41005014], 41 [36.31321427, 39.41182202], 42 [20.54161943, 47.6073278 ], 43 [15.56658469, 28.43798703], 44 [36.3599739, 29.09789437]]) 45 46rudius = 5.196 47 48def bounded_voronoi(bnd, pnts): 49 """ 50 有界なボロノイ図を計算・描画する関数. 51 """ 52 53 # すべての母点のボロノイ領域を有界にするために,ダミー母点を3個追加 54 gn_pnts = np.concatenate([pnts, np.array([[100, 100], [100, -100], [-100, 0]])]) 55 56 # ボロノイ図の計算 57 vor = Voronoi(gn_pnts) 58 59 # 分割する領域をPolygonに 60 bnd_poly = Polygon(bnd) 61 62 # 各ボロノイ領域をしまうリスト 63 vor_polys = [] 64 65 # ダミー以外の母点についての繰り返し 66 for i in range(len(gn_pnts) - 3): 67 68 # 閉空間を考慮しないボロノイ領域 69 vor_poly = [vor.vertices[v] for v in vor.regions[vor.point_region[i]]] 70 # 分割する領域をボロノイ領域の共通部分を計算 71 i_cell = bnd_poly.intersection(Polygon(vor_poly)) 72 73 # 閉空間を考慮したボロノイ領域の頂点座標を格納 74 vor_polys.append(list(i_cell.exterior.coords[:-1])) 75 76 77 # ボロノイ図の描画 78 fig = plt.figure(figsize=(7, 6)) 79 ax = fig.add_subplot(111) 80 81 # 母点 82 ax.scatter(pnts[:,0], pnts[:,1]) 83 84 # ボロノイ領域 85 poly_vor = PolyCollection(vor_polys, edgecolor="black", 86 facecolors="None", linewidth = 1.0) 87 ax.add_collection(poly_vor) 88 89 xmin = np.min(bnd[:,0]) 90 xmax = np.max(bnd[:,0]) 91 ymin = np.min(bnd[:,1]) 92 ymax = np.max(bnd[:,1]) 93 94 ax.set_xlim(xmin-0.1, xmax+0.1) 95 ax.set_ylim(ymin-0.1, ymax+0.1) 96 ax.set_aspect('equal') 97 98 fig.savefig('voronoi.pdf') 99 100 return vor_polys 101 102# ボロノイ図の計算・描画 103vor_polys = bounded_voronoi(data, pt) 104print(vor_polys) 105

試したこと

具体的なコードはキータ(URL:https://qiita.com/supbon2/items/30e0cb49c9338e721b8c)を参考にさせていただきました.
基本的には描画も可能ではあるのですが,母点の座標データを15個以上に設定した場合にのみこのようなエラーが発生するようです.

上記のコードは25個の座標が指定してありますが,この数を14個以下に変更した際は想定通り動いていたので間違いないと思われます.

補足情報

他にも必要な情報等ございましたらコメントにてよろしくお願いします。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

  • すべてのボロノイ領域を有界にするために,ダミーの母点を3個追加する.

これが実現できていないからです。
全ての点がダミーの母点でできる三角形の中に入らなければならないのですが、
[33.1668619, 68.509277 ]は直線y = 0.5x + 50よりも上にありますね。

Pythonで有界な(閉じた)ボロノイ図を計算・描画するの場合は、全ての点の座標が0と1の間にあるので、ダミーの母点でできる三角形の中に入っています。

python

1 gn_pnts = np.concatenate([pnts, np.array([[100, 100], [100, -100], [-100, 0]])])

を```python
gn_pnts = np.concatenate([pnts, np.array([[1000, 1000], [1000, -1000], [-1000, 0]])])

に変更しましょう。

投稿2021/12/20 11:29

ppaul

総合スコア24670

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

narimi

2021/12/21 02:37

なるほど,,, 最初に設定した母点から成る三角形内に収まっていないのがたまたま15個目だったってことですね. とても分かりやすかったです. ありがとうございました!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.35%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問