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:
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: