Como pasé una cantidad considerable de tiempo en esto, me gustaría compartir mi solución sobre cómo conseguir la Voronoi polígonos en lugar de solo los bordes.
El código está en https://gist.github.com/letmaik/8803860 y se extiende en la solución de tauran.
Primero, cambié el código para darme vértices y (pares de) índices (= bordes) por separado, ya que muchos cálculos se pueden simplificar cuando se trabaja en índices en lugar de coordenadas de puntos.
Luego, en el método voronoi_cell_lines
, determino qué bordes pertenecen a qué celdas. Para eso utilizo la solución propuesta de Alink de una pregunta relacionada. Es decir, para cada borde, encuentre los dos puntos de entrada más cercanos (= celdas) y cree un mapeo a partir de eso.
El último paso es crear los polígonos reales (consulte el método voronoi_polygons
).Primero, las celdas externas que tienen bordes colgantes necesitan estar cerradas. Esto es tan simple como mirar a través de todos los bordes y verificar cuáles tienen solo un borde contiguo. Puede haber cero o dos de esos bordes. En el caso de dos, los conecto introduciendo un borde adicional.
Finalmente, los bordes desordenados en cada celda deben ponerse en el orden correcto para derivar un polígono de ellos.
El uso es:
P = np.random.random((100,2))
fig = plt.figure(figsize=(4.5,4.5))
axes = plt.subplot(1,1,1)
plt.axis([-0.05,1.05,-0.05,1.05])
vertices, lineIndices = voronoi(P)
cells = voronoi_cell_lines(P, vertices, lineIndices)
polys = voronoi_polygons(cells)
for pIdx, polyIndices in polys.items():
poly = vertices[np.asarray(polyIndices)]
p = matplotlib.patches.Polygon(poly, facecolor=np.random.rand(3,1))
axes.add_patch(p)
X,Y = P[:,0],P[:,1]
plt.scatter(X, Y, marker='.', zorder=2)
plt.axis([-0.05,1.05,-0.05,1.05])
plt.show()
que emite:

El código no es probablemente adecuada para un gran número de puntos de entrada y se puede mejorar en algunas áreas. Sin embargo, puede ser útil para otras personas que tienen problemas similares.
¡Vuelva a esto, una respuesta brillante, muchas gracias! – EdwardAndo
+1. Gracias por este código 'ncross2' toma' u' y 'v' son argumentos, pero calcula un valor que depende solo de' a' y 'b'. Tal vez el 'a' y' b' deberían ser reemplazados por 'u' y' v'? – unutbu
Encontrar los bordes hasta el infinito es bastante fácil usando el atributo convex_hull. Puedo publicar el código si lo deseas. – meawoppl