I generated 20 random points and applied Delaunay triangulation and created a visualization. I can't understand why there are always some points on the outside that aren't connected. I've looked in the qhull documentation, but I can't find the setting that would solve my issue. I also tried changing the seed, but even with different numbers, the problem persists. I tried the opitions in scipy.spatial.Delaunay like furthest_site, incremental and qhull_options="QJ" but they didn't solved the issue.
import numpy as np
from scipy.spatial import Delaunay
import matplotlib.pyplot as plt
#The points that I used
np.random.seed(10)
points = 10 * np.random.rand(20, 2)
#qhull_options = "QJ"
tri = Delaunay(points)
plt.plot(points[:, 0], points[:, 1], 'o', markersize=8, label='Points')
for simplex in tri.simplices:
plt.plot(points[simplex, 0], points[simplex, 1], 'k-')
#point1 = points[simplex, 0]
#point2 = points[simplex, 1]
#distance = np.linalg.norm(point1 - point2)
#point_pairs.append((point1, point2))
#distances.append(distance)
plt.xlabel('X')
plt.ylabel('Y')
plt.title('Delaunay Triangulation ')
plt.legend()
plt.axis('equal')
plt.show()
"""
[[7.71320643 0.20751949]
[6.33648235 7.48803883]
[4.98507012 2.24796646]
[1.98062865 7.60530712]
[1.69110837 0.88339814]
[6.85359818 9.53393346]
[0.03948266 5.12192263]
[8.12620962 6.12526067]
[7.21755317 2.91876068]
[9.17774123 7.14575783]
[5.42544368 1.42170048]
[3.7334076 6.74133615]
[4.41833174 4.34013993]
[6.17766978 5.13138243]
[6.50397182 6.01038953]
[8.05223197 5.21647152]
[9.08648881 3.19236089]
[0.90459349 3.00700057]
[1.13984362 8.28681326]
[0.46896319 6.26287148]]
"""
'''
from scipy.spatial import Delaunay
import numpy as np
import matplotlib.pyplot as plt
np.random.seed(1234)
points=np.random.rand(10,2)
tri=Delaunay(points)
plt.scatter(points[:,0], points[:,1])
for s in tri.simplices:
plt.plot(points[s,0], points[s,1], 'k-')
plt.show()
Its shows:
I was lucky with my seed, because (unlike yours — even tho, without bragging, I knew anyway what was the problem from yours too) it make it obvious what the problem is: that single line at the bottom cannot be part of a triangle (on your example, you seem to have only closed triangles
The reason why, your, otherwise quite clever, way to draw triangles, just draw 2 lines of each triangle. Each simplex
is a triplet of indexes. You use fancy indexing to turn those into a triplet of x
and a triplet of y
. And plot those. But in matplotlib, when you plot 3 x and 3 y you get 2 lines, not 3.
Just draw the 1st triangle only to be sure (we are lucky again, that 1st triangle happen to be the one we already noticed)
plt.scatter(points[:,0], points[:,1])
for s in tri.simplices:
plt.plot(points[s,0], points[s,1], 'k-')
break
So, you see, 2 lines (tho I am sure you didn't really need convincing at this point. That is the kind of bug sometimes hard to find, but that seem obvious once seen).
So, one, solution could be to use plt.fill
instead (with option fill=False
, which may seem oxymoronic, since that means fill, but don't fill. But fill
role is to close the loop, when drawing, and to fill the inside, unless asked not to)
plt.scatter(points[:,0], points[:,1])
for s in tri.simplices:
plt.fill(points[s,0], points[s,1], fill=False)
Another option could have been to alter all s
to add the first point at the end
plt.scatter(points[:,0], points[:,1])
for s in tri.simplices:
t=s.tolist()+[s[0]]
plt.plot(points[t,0], points[t,1], 'k-')
showing the exact same result.
But fill, without fill=False
can also make it quite clear where the triangles are:
for s in tri.simplices:
plt.fill(points[s,0], points[s,1])
plt.scatter(points[:,0], points[:,1]) # I need to draw the points after, or otherwise they are covered by filled triangles
I missed the fact that, while I was playing with my own example, you edited your post to create a MRE. So now I can show what happens with your seed