I have a text file with xy-coordinates called xy.txt
.
JavaScriptx491491129.66150677 -98.39336541
229.66150677 -98.39337576
329.66150651 -98.39336541
429.66150328 -98.39337576
529.66150677 -98.39336475
629.66150677 -98.39338611
729.66150393 -98.39338611
829.66150677 -98.39339646
929.66150659 -98.39339646
1029.66150677 -98.39339693
1129.66151576 -98.39334472
1229.66151576 -98.39335506
1329.66151511 -98.39334472
1429.66151058 -98.39335506
1529.66151576 -98.39334322
1629.66151576 -98.39336541
1729.66151576 -98.39337576
1829.66151576 -98.39338611
1929.66151576 -98.39339646
2029.66151576 -98.39340681
2129.66151067 -98.39340681
2229.66151576 -98.39341515
2329.66152475 -98.39332402
2429.66152475 -98.39333437
2529.66152443 -98.39332402
2629.66151973 -98.39333437
2729.66152475 -98.39332332
2829.66152475 -98.39334472
2929.66152475 -98.39335506
3029.66152475 -98.39336541
3129.66152475 -98.39337576
3229.66152475 -98.39338611
3329.66152475 -98.39339646
3429.66152475 -98.39340681
3529.66152475 -98.39341716
3629.66151699 -98.39341716
3729.66152475 -98.39342722
3829.66153375 -98.39331367
3929.66153375 -98.39332402
4029.6615302 -98.39331367
4129.66153375 -98.3933086
4229.66153375 -98.39333437
4329.66153375 -98.39334472
4429.66153375 -98.39335506
4529.66153375 -98.39336541
4629.66153375 -98.39337576
4729.66153375 -98.39338611
4829.66153375 -98.39339646
4929.66153375 -98.39340681
5029.66153375 -98.39341716
5129.66153375 -98.39342751
5229.66152507 -98.39342751
5329.66153375 -98.39343443
5429.66154274 -98.39330332
5529.66154274 -98.39331367
5629.66153745 -98.39330332
5729.66154274 -98.39329625
5829.66154274 -98.39332402
5929.66154274 -98.39333437
6029.66154274 -98.39334472
6129.66154274 -98.39335506
6229.66154274 -98.39336541
6329.66154274 -98.39337576
6429.66154274 -98.39338611
6529.66154274 -98.39339646
6629.66154274 -98.39340681
6729.66154274 -98.39341716
6829.66154274 -98.39342751
6929.66154274 -98.39343786
7029.66153992 -98.39343786
7129.66154274 -98.3934387
7229.66155173 -98.39329297
7329.66155173 -98.39330332
7429.6615457 -98.39329297
7529.66155173 -98.39328644
7629.66155173 -98.39331367
7729.66155173 -98.39332402
7829.66155173 -98.39333437
7929.66155173 -98.39334472
8029.66155173 -98.39335506
8129.66155173 -98.39336541
8229.66155173 -98.39337576
8329.66155173 -98.39338611
8429.66155173 -98.39339646
8529.66155173 -98.39340681
8629.66155173 -98.39341716
8729.66155173 -98.39342751
8829.66155173 -98.39343786
8929.66155173 -98.39344106
9029.66156073 -98.39328262
9129.66156073 -98.39329297
9229.66155555 -98.39328262
9329.66156073 -98.39327744
9429.66156073 -98.39330332
9529.66156073 -98.39331367
9629.66156073 -98.39332402
9729.66156073 -98.39333437
9829.66156073 -98.39334472
9929.66156073 -98.39335506
10029.66156073 -98.39336541
10129.66156073 -98.39337576
10229.66156073 -98.39338611
10329.66156073 -98.39339646
10429.66156073 -98.39340681
10529.66156073 -98.39341716
10629.66156073 -98.39342751
10729.66156073 -98.39343786
10829.66156073 -98.39344196
10929.66156972 -98.39327227
11029.66156972 -98.39328262
11129.66156651 -98.39327227
11229.66156972 -98.39326964
11329.66156972 -98.39329297
11429.66156972 -98.39330332
11529.66156972 -98.39331367
11629.66156972 -98.39332402
11729.66156972 -98.39333437
11829.66156972 -98.39334472
11929.66156972 -98.39335506
12029.66156972 -98.39336541
12129.66156972 -98.39337576
12229.66156972 -98.39338611
12329.66156972 -98.39339646
12429.66156972 -98.39340681
12529.66156972 -98.39341716
12629.66156972 -98.39342751
12729.66156972 -98.39343786
12829.66156972 -98.393442
12929.66157871 -98.39327227
13029.66157871 -98.39328262
13129.66157871 -98.39326327
13229.66157871 -98.39329297
13329.66157871 -98.39330332
13429.66157871 -98.39331367
13529.66157871 -98.39332402
13629.66157871 -98.39333437
13729.66157871 -98.39334472
13829.66157871 -98.39335506
13929.66157871 -98.39336541
14029.66157871 -98.39337576
14129.66157871 -98.39338611
14229.66157871 -98.39339646
14329.66157871 -98.39340681
14429.66157871 -98.39341716
14529.66157871 -98.39342751
14629.66157871 -98.39343786
14729.66157871 -98.39344084
14829.66158771 -98.39326192
14929.66158771 -98.39327227
15029.66158097 -98.39326192
15129.66158771 -98.39325788
15229.66158771 -98.39328262
15329.66158771 -98.39329297
15429.66158771 -98.39330332
15529.66158771 -98.39331367
15629.66158771 -98.39332402
15729.66158771 -98.39333437
15829.66158771 -98.39334472
15929.66158771 -98.39335506
16029.66158771 -98.39336541
16129.66158771 -98.39337576
16229.66158771 -98.39338611
16329.66158771 -98.39339646
16429.66158771 -98.39340681
16529.66158771 -98.39341716
16629.66158771 -98.39342751
16729.66158771 -98.39343786
16829.66158771 -98.39343926
16929.66159226 -98.39343786
17029.6615967 -98.39326192
17129.6615967 -98.39327227
17229.6615967 -98.39325426
17329.6615967 -98.39328262
17429.6615967 -98.39329297
17529.6615967 -98.39330332
17629.6615967 -98.39331367
17729.6615967 -98.39332402
17829.6615967 -98.39333437
17929.6615967 -98.39334472
18029.6615967 -98.39335506
18129.6615967 -98.39336541
18229.6615967 -98.39337576
18329.6615967 -98.39338611
18429.6615967 -98.39339646
18529.6615967 -98.39340681
18629.6615967 -98.39341716
18729.6615967 -98.39342751
18829.6615967 -98.39343623
18929.66160569 -98.39325157
19029.66160569 -98.39326192
19129.66160564 -98.39325157
19229.66160569 -98.39325156
19329.66160569 -98.39327227
19429.66160569 -98.39328262
19529.66160569 -98.39329297
19629.66160569 -98.39330332
19729.66160569 -98.39331367
19829.66160569 -98.39332402
19929.66160569 -98.39333437
20029.66160569 -98.39334472
20129.66160569 -98.39335506
20229.66160569 -98.39336541
20329.66160569 -98.39337576
20429.66160569 -98.39338611
20529.66160569 -98.39339646
20629.66160569 -98.39340681
20729.66160569 -98.39341716
20829.66160569 -98.39342751
20929.66160569 -98.39343291
21029.66161468 -98.39325157
21129.66161468 -98.39326192
21229.66161468 -98.39324921
21329.66161468 -98.39327227
21429.66161468 -98.39328262
21529.66161468 -98.39329297
21629.66161468 -98.39330332
21729.66161468 -98.39331367
21829.66161468 -98.39332402
21929.66161468 -98.39333437
22029.66161468 -98.39334472
22129.66161468 -98.39335506
22229.66161468 -98.39336541
22329.66161468 -98.39337576
22429.66161468 -98.39338611
22529.66161468 -98.39339646
22629.66161468 -98.39340681
22729.66161468 -98.39341716
22829.66161468 -98.39342751
22929.66161468 -98.39342823
23029.66161592 -98.39342751
23129.66162368 -98.39325157
23229.66162368 -98.39326192
23329.66162368 -98.39324697
23429.66162368 -98.39327227
23529.66162368 -98.39328262
23629.66162368 -98.39329297
23729.66162368 -98.39330332
23829.66162368 -98.39331367
23929.66162368 -98.39332402
24029.66162368 -98.39333437
24129.66162368 -98.39334472
24229.66162368 -98.39335506
24329.66162368 -98.39336541
24429.66162368 -98.39337576
24529.66162368 -98.39338611
24629.66162368 -98.39339646
24729.66162368 -98.39340681
24829.66162368 -98.39341716
24929.66162368 -98.39342302
25029.66163267 -98.39325157
25129.66163267 -98.39326192
25229.66163267 -98.39324642
25329.66163267 -98.39327227
25429.66163267 -98.39328262
25529.66163267 -98.39329297
25629.66163267 -98.39330332
25729.66163267 -98.39331367
25829.66163267 -98.39332402
25929.66163267 -98.39333437
26029.66163267 -98.39334472
26129.66163267 -98.39335506
26229.66163267 -98.39336541
26329.66163267 -98.39337576
26429.66163267 -98.39338611
26529.66163267 -98.39339646
26629.66163267 -98.39340681
26729.66163267 -98.39341716
26829.66163267 -98.39341722
26929.66163275 -98.39341716
27029.66164166 -98.39325157
27129.66164166 -98.39326192
27229.66164166 -98.39324588
27329.66164166 -98.39327227
27429.66164166 -98.39328262
27529.66164166 -98.39329297
27629.66164166 -98.39330332
27729.66164166 -98.39331367
27829.66164166 -98.39332402
27929.66164166 -98.39333437
28029.66164166 -98.39334472
28129.66164166 -98.39335506
28229.66164166 -98.39336541
28329.66164166 -98.39337576
28429.66164166 -98.39338611
28529.66164166 -98.39339646
28629.66164166 -98.39340681
28729.66164166 -98.39341103
28829.66164749 -98.39340681
28929.66165066 -98.39325157
29029.66165066 -98.39326192
29129.66165066 -98.39324533
29229.66165066 -98.39327227
29329.66165066 -98.39328262
29429.66165066 -98.39329297
29529.66165066 -98.39330332
29629.66165066 -98.39331367
29729.66165066 -98.39332402
29829.66165066 -98.39333437
29929.66165066 -98.39334472
30029.66165066 -98.39335506
30129.66165066 -98.39336541
30229.66165066 -98.39337576
30329.66165066 -98.39338611
30429.66165066 -98.39339646
30529.66165066 -98.39340447
30629.66165965 -98.39325157
30729.66165965 -98.39326192
30829.66165965 -98.39324479
30929.66165965 -98.39327227
31029.66165965 -98.39328262
31129.66165965 -98.39329297
31229.66165965 -98.39330332
31329.66165965 -98.39331367
31429.66165965 -98.39332402
31529.66165965 -98.39333437
31629.66165965 -98.39334472
31729.66165965 -98.39335506
31829.66165965 -98.39336541
31929.66165965 -98.39337576
32029.66165965 -98.39338611
32129.66165965 -98.39339646
32229.66165965 -98.39339783
32329.6616615 -98.39339646
32429.66166864 -98.39325157
32529.66166864 -98.39326192
32629.66166864 -98.39324424
32729.66166864 -98.39327227
32829.66166864 -98.39328262
32929.66166864 -98.39329297
33029.66166864 -98.39330332
33129.66166864 -98.39331367
33229.66166864 -98.39332402
33329.66166864 -98.39333437
33429.66166864 -98.39334472
33529.66166864 -98.39335506
33629.66166864 -98.39336541
33729.66166864 -98.39337576
33829.66166864 -98.39338611
33929.66166864 -98.39339119
34029.66167552 -98.39338611
34129.66167764 -98.39325157
34229.66167764 -98.39326192
34329.66167764 -98.3932437
34429.66167764 -98.39327227
34529.66167764 -98.39328262
34629.66167764 -98.39329297
34729.66167764 -98.39330332
34829.66167764 -98.39331367
34929.66167764 -98.39332402
35029.66167764 -98.39333437
35129.66167764 -98.39334472
35229.66167764 -98.39335506
35329.66167764 -98.39336541
35429.66167764 -98.39337576
35529.66167764 -98.39338455
35629.66168663 -98.39325157
35729.66168663 -98.39326192
35829.66168663 -98.39324315
35929.66168663 -98.39327227
36029.66168663 -98.39328262
36129.66168663 -98.39329297
36229.66168663 -98.39330332
36329.66168663 -98.39331367
36429.66168663 -98.39332402
36529.66168663 -98.39333437
36629.66168663 -98.39334472
36729.66168663 -98.39335506
36829.66168663 -98.39336541
36929.66168663 -98.39337576
37029.66168663 -98.39337791
37129.66168954 -98.39337576
37229.66169562 -98.39325157
37329.66169562 -98.39326192
37429.66169562 -98.39324277
37529.66169562 -98.39327227
37629.66169562 -98.39328262
37729.66169562 -98.39329297
37829.66169562 -98.39330332
37929.66169562 -98.39331367
38029.66169562 -98.39332402
38129.66169562 -98.39333437
38229.66169562 -98.39334472
38329.66169562 -98.39335506
38429.66169562 -98.39336541
38529.66169562 -98.39337127
38629.66170356 -98.39336541
38729.66170462 -98.39325157
38829.66170462 -98.39326192
38929.66170462 -98.39324245
39029.66170462 -98.39327227
39129.66170462 -98.39328262
39229.66170462 -98.39329297
39329.66170462 -98.39330332
39429.66170462 -98.39331367
39529.66170462 -98.39332402
39629.66170462 -98.39333437
39729.66170462 -98.39334472
39829.66170462 -98.39335506
39929.66170462 -98.39336463
40029.66171361 -98.39325157
40129.66171361 -98.39326192
40229.66171361 -98.39324213
40329.66171361 -98.39327227
40429.66171361 -98.39328262
40529.66171361 -98.39329297
40629.66171361 -98.39330332
40729.66171361 -98.39331367
40829.66171361 -98.39332402
40929.66171361 -98.39333437
41029.66171361 -98.39334472
41129.66171361 -98.39335506
41229.66171361 -98.39335799
41329.66171758 -98.39335506
41429.6617226 -98.39325157
41529.6617226 -98.39326192
41629.6617226 -98.393242
41729.6617226 -98.39327227
41829.6617226 -98.39328262
41929.6617226 -98.39329297
42029.6617226 -98.39330332
42129.6617226 -98.39331367
42229.6617226 -98.39332402
42329.6617226 -98.39333437
42429.6617226 -98.39334472
42529.6617226 -98.39335135
42629.66173159 -98.39334472
42729.6617316 -98.39325157
42829.6617316 -98.39326192
42929.6617316 -98.393242
43029.6617316 -98.39327227
43129.6617316 -98.39328262
43229.6617316 -98.39329297
43329.6617316 -98.39330332
43429.6617316 -98.39331367
43529.6617316 -98.39332402
43629.6617316 -98.39333437
43729.6617316 -98.39334471
43829.66174059 -98.39325157
43929.66174059 -98.39326192
44029.66174059 -98.393242
44129.66174059 -98.39327227
44229.66174059 -98.39328262
44329.66174059 -98.39329297
44429.66174059 -98.39330332
44529.66174059 -98.39331367
44629.66174059 -98.39332402
44729.66174059 -98.39333437
44829.66174059 -98.39333807
44929.66174561 -98.39333437
45029.66174958 -98.39325157
45129.66174958 -98.39326192
45229.66174958 -98.39324293
45329.66174958 -98.39327227
45429.66174958 -98.39328262
45529.66174958 -98.39329297
45629.66174958 -98.39330332
45729.66174958 -98.39331367
45829.66174958 -98.39332402
45929.66174958 -98.39333143
46029.66175858 -98.39325157
46129.66175858 -98.39326192
46229.66176663 -98.39325157
46329.66176757 -98.39326192
46429.66175858 -98.39324585
46529.66175858 -98.39327227
46629.66175858 -98.39328262
46729.66175858 -98.39329297
46829.66175858 -98.39330332
46929.66175858 -98.39331367
47029.66175858 -98.39332402
47129.66175858 -98.39332427
47229.6617589 -98.39332402
47329.66176757 -98.39327227
47429.66177412 -98.39326192
47529.66177656 -98.39327227
47629.66176757 -98.3932525
47729.66176757 -98.39328262
47829.66176757 -98.39329297
47929.66176757 -98.39330332
48029.66176757 -98.39331367
48129.66177543 -98.39330332
48229.66176974 -98.39331367
48329.66176757 -98.3933162
48429.66177656 -98.39328262
48529.66177775 -98.39327227
48629.66177872 -98.39328262
48729.66177656 -98.39326599
48829.66177656 -98.39329297
48929.66177855 -98.39329297
49029.66177656 -98.39330028
491
I read the file using
import numpy as np
xy = np.loadtxt('xy.txt')
x, y = xy[:, 0], xy[:, 1]
and I can plot the points with
import matplotlib.pyplot as plt
plt.plot(x, y, 'o', color='black', markersize=6)
plt.show()
Visually the data looks as follows:
I want to retrieve the xy-coordinates of the points that form the boundary of the shape. Answers on similar questions suggest to use Concave Hull. With the help of this blog I write the following code:
from scipy import spatial
hull = spatial.ConvexHull(xy, incremental=False, qhull_options='Qt')
hull_indices = hull.vertices
boundary_x = []
boundary_y = []
for i in range(len(hull_indices)):
index = hull_indices[i]
boundary_x.append(xy[index, 0].astype('float32'))
boundary_y.append(xy[index, 1].astype('float32'))
plt.plot(boundary_x, boundary_y, 'o', color='red', markersize=6)
plt.show()
The output looks like
Clearly the red points are not the boundary points. Some are enclosed by other points and they all are different from the original points. How do I define the boundary points in terms of the original points? Please advice
Advertisement
Answer
When I try to reproduce your code the convexHull function works perfectly. I changed your code so that the positions of black and red circles are rounded in the same way. And I reduced the radius of the red circles so you can better see if everything fits.
import numpy as np
import matplotlib.pyplot as plt
from scipy import spatial
xy = np.loadtxt('xy.txt')
x, y = xy[:, 0].astype('float64'), xy[:, 1].astype('float64')
hull = spatial.ConvexHull(xy, incremental=False, qhull_options='Qt')
hull_indices = hull.vertices
boundary_x = []
boundary_y = []
for i in range(len(hull_indices)):
index = hull_indices[i]
boundary_x.append(xy[index, 0].astype('float64'))
boundary_y.append(xy[index, 1].astype('float64'))
plt.plot(x, y, 'o', color='black', markersize=6)
plt.plot(boundary_x, boundary_y, 'o', color='red', markersize=4)
plt.show()
Result:
Update: If you need the concave parts of the boundary, too, you can use the python package alphashape instead and calculate the alpha shape. The points in your test data are very close, so I had to normalize the coordinates and adjust the alpha value to get reasonable results.
import numpy as np
import matplotlib.pyplot as plt
import alphashape
data = np.loadtxt('xy.txt')
xy = (data + [-29.0, 98.0]) * 10
x, y = xy[:, 0], xy[:, 1]
shape = alphashape.alphashape(xy, alpha=500.0)
shape_x, shape_y = shape.exterior.coords.xy
plt.plot(x, y, 'o', color='black', markersize=6)
plt.plot(shape_x, shape_y, 'o', color='red', markersize=4)
plt.show()
Result: