Skip to content
Advertisement

Find boundary points of xy coordinates

I have a text file with xy-coordinates called xy.txt.

29.66150677   -98.39336541
29.66150677   -98.39337576
29.66150651   -98.39336541
29.66150328   -98.39337576
29.66150677   -98.39336475
29.66150677   -98.39338611
29.66150393   -98.39338611
29.66150677   -98.39339646
29.66150659   -98.39339646
29.66150677   -98.39339693
29.66151576   -98.39334472
29.66151576   -98.39335506
29.66151511   -98.39334472
29.66151058   -98.39335506
29.66151576   -98.39334322
29.66151576   -98.39336541
29.66151576   -98.39337576
29.66151576   -98.39338611
29.66151576   -98.39339646
29.66151576   -98.39340681
29.66151067   -98.39340681
29.66151576   -98.39341515
29.66152475   -98.39332402
29.66152475   -98.39333437
29.66152443   -98.39332402
29.66151973   -98.39333437
29.66152475   -98.39332332
29.66152475   -98.39334472
29.66152475   -98.39335506
29.66152475   -98.39336541
29.66152475   -98.39337576
29.66152475   -98.39338611
29.66152475   -98.39339646
29.66152475   -98.39340681
29.66152475   -98.39341716
29.66151699   -98.39341716
29.66152475   -98.39342722
29.66153375   -98.39331367
29.66153375   -98.39332402
29.6615302    -98.39331367
29.66153375   -98.3933086
29.66153375   -98.39333437
29.66153375   -98.39334472
29.66153375   -98.39335506
29.66153375   -98.39336541
29.66153375   -98.39337576
29.66153375   -98.39338611
29.66153375   -98.39339646
29.66153375   -98.39340681
29.66153375   -98.39341716
29.66153375   -98.39342751
29.66152507   -98.39342751
29.66153375   -98.39343443
29.66154274   -98.39330332
29.66154274   -98.39331367
29.66153745   -98.39330332
29.66154274   -98.39329625
29.66154274   -98.39332402
29.66154274   -98.39333437
29.66154274   -98.39334472
29.66154274   -98.39335506
29.66154274   -98.39336541
29.66154274   -98.39337576
29.66154274   -98.39338611
29.66154274   -98.39339646
29.66154274   -98.39340681
29.66154274   -98.39341716
29.66154274   -98.39342751
29.66154274   -98.39343786
29.66153992   -98.39343786
29.66154274   -98.3934387
29.66155173   -98.39329297
29.66155173   -98.39330332
29.6615457    -98.39329297
29.66155173   -98.39328644
29.66155173   -98.39331367
29.66155173   -98.39332402
29.66155173   -98.39333437
29.66155173   -98.39334472
29.66155173   -98.39335506
29.66155173   -98.39336541
29.66155173   -98.39337576
29.66155173   -98.39338611
29.66155173   -98.39339646
29.66155173   -98.39340681
29.66155173   -98.39341716
29.66155173   -98.39342751
29.66155173   -98.39343786
29.66155173   -98.39344106
29.66156073   -98.39328262
29.66156073   -98.39329297
29.66155555   -98.39328262
29.66156073   -98.39327744
29.66156073   -98.39330332
29.66156073   -98.39331367
29.66156073   -98.39332402
29.66156073   -98.39333437
29.66156073   -98.39334472
29.66156073   -98.39335506
29.66156073   -98.39336541
29.66156073   -98.39337576
29.66156073   -98.39338611
29.66156073   -98.39339646
29.66156073   -98.39340681
29.66156073   -98.39341716
29.66156073   -98.39342751
29.66156073   -98.39343786
29.66156073   -98.39344196
29.66156972   -98.39327227
29.66156972   -98.39328262
29.66156651   -98.39327227
29.66156972   -98.39326964
29.66156972   -98.39329297
29.66156972   -98.39330332
29.66156972   -98.39331367
29.66156972   -98.39332402
29.66156972   -98.39333437
29.66156972   -98.39334472
29.66156972   -98.39335506
29.66156972   -98.39336541
29.66156972   -98.39337576
29.66156972   -98.39338611
29.66156972   -98.39339646
29.66156972   -98.39340681
29.66156972   -98.39341716
29.66156972   -98.39342751
29.66156972   -98.39343786
29.66156972   -98.393442
29.66157871   -98.39327227
29.66157871   -98.39328262
29.66157871   -98.39326327
29.66157871   -98.39329297
29.66157871   -98.39330332
29.66157871   -98.39331367
29.66157871   -98.39332402
29.66157871   -98.39333437
29.66157871   -98.39334472
29.66157871   -98.39335506
29.66157871   -98.39336541
29.66157871   -98.39337576
29.66157871   -98.39338611
29.66157871   -98.39339646
29.66157871   -98.39340681
29.66157871   -98.39341716
29.66157871   -98.39342751
29.66157871   -98.39343786
29.66157871   -98.39344084
29.66158771   -98.39326192
29.66158771   -98.39327227
29.66158097   -98.39326192
29.66158771   -98.39325788
29.66158771   -98.39328262
29.66158771   -98.39329297
29.66158771   -98.39330332
29.66158771   -98.39331367
29.66158771   -98.39332402
29.66158771   -98.39333437
29.66158771   -98.39334472
29.66158771   -98.39335506
29.66158771   -98.39336541
29.66158771   -98.39337576
29.66158771   -98.39338611
29.66158771   -98.39339646
29.66158771   -98.39340681
29.66158771   -98.39341716
29.66158771   -98.39342751
29.66158771   -98.39343786
29.66158771   -98.39343926
29.66159226   -98.39343786
29.6615967    -98.39326192
29.6615967    -98.39327227
29.6615967    -98.39325426
29.6615967    -98.39328262
29.6615967    -98.39329297
29.6615967    -98.39330332
29.6615967    -98.39331367
29.6615967    -98.39332402
29.6615967    -98.39333437
29.6615967    -98.39334472
29.6615967    -98.39335506
29.6615967    -98.39336541
29.6615967    -98.39337576
29.6615967    -98.39338611
29.6615967    -98.39339646
29.6615967    -98.39340681
29.6615967    -98.39341716
29.6615967    -98.39342751
29.6615967    -98.39343623
29.66160569   -98.39325157
29.66160569   -98.39326192
29.66160564   -98.39325157
29.66160569   -98.39325156
29.66160569   -98.39327227
29.66160569   -98.39328262
29.66160569   -98.39329297
29.66160569   -98.39330332
29.66160569   -98.39331367
29.66160569   -98.39332402
29.66160569   -98.39333437
29.66160569   -98.39334472
29.66160569   -98.39335506
29.66160569   -98.39336541
29.66160569   -98.39337576
29.66160569   -98.39338611
29.66160569   -98.39339646
29.66160569   -98.39340681
29.66160569   -98.39341716
29.66160569   -98.39342751
29.66160569   -98.39343291
29.66161468   -98.39325157
29.66161468   -98.39326192
29.66161468   -98.39324921
29.66161468   -98.39327227
29.66161468   -98.39328262
29.66161468   -98.39329297
29.66161468   -98.39330332
29.66161468   -98.39331367
29.66161468   -98.39332402
29.66161468   -98.39333437
29.66161468   -98.39334472
29.66161468   -98.39335506
29.66161468   -98.39336541
29.66161468   -98.39337576
29.66161468   -98.39338611
29.66161468   -98.39339646
29.66161468   -98.39340681
29.66161468   -98.39341716
29.66161468   -98.39342751
29.66161468   -98.39342823
29.66161592   -98.39342751
29.66162368   -98.39325157
29.66162368   -98.39326192
29.66162368   -98.39324697
29.66162368   -98.39327227
29.66162368   -98.39328262
29.66162368   -98.39329297
29.66162368   -98.39330332
29.66162368   -98.39331367
29.66162368   -98.39332402
29.66162368   -98.39333437
29.66162368   -98.39334472
29.66162368   -98.39335506
29.66162368   -98.39336541
29.66162368   -98.39337576
29.66162368   -98.39338611
29.66162368   -98.39339646
29.66162368   -98.39340681
29.66162368   -98.39341716
29.66162368   -98.39342302
29.66163267   -98.39325157
29.66163267   -98.39326192
29.66163267   -98.39324642
29.66163267   -98.39327227
29.66163267   -98.39328262
29.66163267   -98.39329297
29.66163267   -98.39330332
29.66163267   -98.39331367
29.66163267   -98.39332402
29.66163267   -98.39333437
29.66163267   -98.39334472
29.66163267   -98.39335506
29.66163267   -98.39336541
29.66163267   -98.39337576
29.66163267   -98.39338611
29.66163267   -98.39339646
29.66163267   -98.39340681
29.66163267   -98.39341716
29.66163267   -98.39341722
29.66163275   -98.39341716
29.66164166   -98.39325157
29.66164166   -98.39326192
29.66164166   -98.39324588
29.66164166   -98.39327227
29.66164166   -98.39328262
29.66164166   -98.39329297
29.66164166   -98.39330332
29.66164166   -98.39331367
29.66164166   -98.39332402
29.66164166   -98.39333437
29.66164166   -98.39334472
29.66164166   -98.39335506
29.66164166   -98.39336541
29.66164166   -98.39337576
29.66164166   -98.39338611
29.66164166   -98.39339646
29.66164166   -98.39340681
29.66164166   -98.39341103
29.66164749   -98.39340681
29.66165066   -98.39325157
29.66165066   -98.39326192
29.66165066   -98.39324533
29.66165066   -98.39327227
29.66165066   -98.39328262
29.66165066   -98.39329297
29.66165066   -98.39330332
29.66165066   -98.39331367
29.66165066   -98.39332402
29.66165066   -98.39333437
29.66165066   -98.39334472
29.66165066   -98.39335506
29.66165066   -98.39336541
29.66165066   -98.39337576
29.66165066   -98.39338611
29.66165066   -98.39339646
29.66165066   -98.39340447
29.66165965   -98.39325157
29.66165965   -98.39326192
29.66165965   -98.39324479
29.66165965   -98.39327227
29.66165965   -98.39328262
29.66165965   -98.39329297
29.66165965   -98.39330332
29.66165965   -98.39331367
29.66165965   -98.39332402
29.66165965   -98.39333437
29.66165965   -98.39334472
29.66165965   -98.39335506
29.66165965   -98.39336541
29.66165965   -98.39337576
29.66165965   -98.39338611
29.66165965   -98.39339646
29.66165965   -98.39339783
29.6616615    -98.39339646
29.66166864   -98.39325157
29.66166864   -98.39326192
29.66166864   -98.39324424
29.66166864   -98.39327227
29.66166864   -98.39328262
29.66166864   -98.39329297
29.66166864   -98.39330332
29.66166864   -98.39331367
29.66166864   -98.39332402
29.66166864   -98.39333437
29.66166864   -98.39334472
29.66166864   -98.39335506
29.66166864   -98.39336541
29.66166864   -98.39337576
29.66166864   -98.39338611
29.66166864   -98.39339119
29.66167552   -98.39338611
29.66167764   -98.39325157
29.66167764   -98.39326192
29.66167764   -98.3932437
29.66167764   -98.39327227
29.66167764   -98.39328262
29.66167764   -98.39329297
29.66167764   -98.39330332
29.66167764   -98.39331367
29.66167764   -98.39332402
29.66167764   -98.39333437
29.66167764   -98.39334472
29.66167764   -98.39335506
29.66167764   -98.39336541
29.66167764   -98.39337576
29.66167764   -98.39338455
29.66168663   -98.39325157
29.66168663   -98.39326192
29.66168663   -98.39324315
29.66168663   -98.39327227
29.66168663   -98.39328262
29.66168663   -98.39329297
29.66168663   -98.39330332
29.66168663   -98.39331367
29.66168663   -98.39332402
29.66168663   -98.39333437
29.66168663   -98.39334472
29.66168663   -98.39335506
29.66168663   -98.39336541
29.66168663   -98.39337576
29.66168663   -98.39337791
29.66168954   -98.39337576
29.66169562   -98.39325157
29.66169562   -98.39326192
29.66169562   -98.39324277
29.66169562   -98.39327227
29.66169562   -98.39328262
29.66169562   -98.39329297
29.66169562   -98.39330332
29.66169562   -98.39331367
29.66169562   -98.39332402
29.66169562   -98.39333437
29.66169562   -98.39334472
29.66169562   -98.39335506
29.66169562   -98.39336541
29.66169562   -98.39337127
29.66170356   -98.39336541
29.66170462   -98.39325157
29.66170462   -98.39326192
29.66170462   -98.39324245
29.66170462   -98.39327227
29.66170462   -98.39328262
29.66170462   -98.39329297
29.66170462   -98.39330332
29.66170462   -98.39331367
29.66170462   -98.39332402
29.66170462   -98.39333437
29.66170462   -98.39334472
29.66170462   -98.39335506
29.66170462   -98.39336463
29.66171361   -98.39325157
29.66171361   -98.39326192
29.66171361   -98.39324213
29.66171361   -98.39327227
29.66171361   -98.39328262
29.66171361   -98.39329297
29.66171361   -98.39330332
29.66171361   -98.39331367
29.66171361   -98.39332402
29.66171361   -98.39333437
29.66171361   -98.39334472
29.66171361   -98.39335506
29.66171361   -98.39335799
29.66171758   -98.39335506
29.6617226    -98.39325157
29.6617226    -98.39326192
29.6617226    -98.393242
29.6617226    -98.39327227
29.6617226    -98.39328262
29.6617226    -98.39329297
29.6617226    -98.39330332
29.6617226    -98.39331367
29.6617226    -98.39332402
29.6617226    -98.39333437
29.6617226    -98.39334472
29.6617226    -98.39335135
29.66173159   -98.39334472
29.6617316    -98.39325157
29.6617316    -98.39326192
29.6617316    -98.393242
29.6617316    -98.39327227
29.6617316    -98.39328262
29.6617316    -98.39329297
29.6617316    -98.39330332
29.6617316    -98.39331367
29.6617316    -98.39332402
29.6617316    -98.39333437
29.6617316    -98.39334471
29.66174059   -98.39325157
29.66174059   -98.39326192
29.66174059   -98.393242
29.66174059   -98.39327227
29.66174059   -98.39328262
29.66174059   -98.39329297
29.66174059   -98.39330332
29.66174059   -98.39331367
29.66174059   -98.39332402
29.66174059   -98.39333437
29.66174059   -98.39333807
29.66174561   -98.39333437
29.66174958   -98.39325157
29.66174958   -98.39326192
29.66174958   -98.39324293
29.66174958   -98.39327227
29.66174958   -98.39328262
29.66174958   -98.39329297
29.66174958   -98.39330332
29.66174958   -98.39331367
29.66174958   -98.39332402
29.66174958   -98.39333143
29.66175858   -98.39325157
29.66175858   -98.39326192
29.66176663   -98.39325157
29.66176757   -98.39326192
29.66175858   -98.39324585
29.66175858   -98.39327227
29.66175858   -98.39328262
29.66175858   -98.39329297
29.66175858   -98.39330332
29.66175858   -98.39331367
29.66175858   -98.39332402
29.66175858   -98.39332427
29.6617589    -98.39332402
29.66176757   -98.39327227
29.66177412   -98.39326192
29.66177656   -98.39327227
29.66176757   -98.3932525
29.66176757   -98.39328262
29.66176757   -98.39329297
29.66176757   -98.39330332
29.66176757   -98.39331367
29.66177543   -98.39330332
29.66176974   -98.39331367
29.66176757   -98.3933162
29.66177656   -98.39328262
29.66177775   -98.39327227
29.66177872   -98.39328262
29.66177656   -98.39326599
29.66177656   -98.39329297
29.66177855   -98.39329297
29.66177656   -98.39330028

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:

enter image description here

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

enter image description here

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:

enter image description here

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:

enter image description here

User contributions licensed under: CC BY-SA
6 People found this is helpful
Advertisement