This is my set of data, where I would like to fit a closed curve to, just like this post
array([[ 0.3 , -0.05],
       [ 0.35, -0.05],
       [ 0.4 , -0.05],
       [ 0.45, -0.05],
       [ 0.5 , -0.05],
       [ 0.55, -0.05],
       [ 0.6 , -0.05],
       [ 0.65, -0.05],
       [ 0.7 , -0.05],
       [ 0.75, -0.05],
       [ 0.8 , -0.05],
       [ 0.85, -0.05],
       [ 0.9 , -0.05],
       [ 0.95, -0.05],
       [ 1.  , -0.05],
       [ 1.05, -0.05],
       [ 1.1 , -0.05],
       [ 1.15, -0.05],
       [ 1.2 , -0.05],
       [ 1.25, -0.05],
       [ 1.3 , -0.05],
       [ 1.35, -0.05],
       [ 1.4 , -0.05],
       [ 1.45, -0.05],
       [ 1.5 , -0.05],
       [ 1.55, -0.05],
       [ 1.6 , -0.05],
       [ 1.65, -0.05],
       [ 1.7 , -0.05],
       [ 1.75, -0.05],
       [ 1.8 , -0.05],
       [ 0.  , -0.1 ],
       [ 0.05, -0.1 ],
       [ 0.  , -0.15],
       [ 2.1 , -0.15],
       [ 2.15, -0.15],
       [ 0.  , -0.2 ],
       [ 2.1 , -0.2 ],
       [ 2.15, -0.2 ],
       [ 2.2 , -0.2 ],
       [ 2.2 , -0.25],
       [ 2.35, -0.35],
       [-0.15, -0.4 ],
       [ 2.35, -0.4 ],
       [-0.15, -0.45],
       [ 2.35, -0.45],
       [ 2.4 , -0.45],
       [ 2.35, -0.5 ],
       [ 2.4 , -0.5 ],
       [ 2.4 , -0.55],
       [-0.25, -0.6 ],
       [-0.2 , -0.6 ],
       [ 2.4 , -0.6 ],
       [ 2.45, -0.6 ],
       [-0.4 , -0.65],
       [ 2.45, -0.65],
       [-0.4 , -0.7 ],
       [ 2.45, -0.7 ],
       [ 2.5 , -0.7 ],
       [ 2.45, -0.75],
       [ 2.45, -0.8 ],
       [-0.5 , -0.85],
       [ 2.45, -0.85],
       [ 2.5 , -0.85],
       [-0.5 , -0.9 ],
       [ 2.45, -0.9 ],
       [ 2.5 , -0.9 ],
       [-0.5 , -0.95],
       [ 2.5 , -0.95],
       [-0.5 , -1.  ],
       [ 2.5 , -1.  ],
       [-0.5 , -1.05],
       [-0.45, -1.05],
       [ 2.5 , -1.05],
       [-0.5 , -1.1 ],
       [-0.45, -1.1 ],
       [ 2.5 , -1.1 ],
       [ 2.55, -1.1 ],
       [-0.5 , -1.15],
       [-0.45, -1.15],
       [ 2.5 , -1.15],
       [ 2.55, -1.15],
       [-0.5 , -1.2 ],
       [-0.45, -1.2 ],
       [ 2.5 , -1.2 ],
       [ 2.55, -1.2 ],
       [-0.45, -1.25],
       [ 2.55, -1.25],
       [-0.45, -1.3 ],
       [ 2.55, -1.3 ],
       [-0.45, -1.35],
       [ 2.55, -1.35],
       [-0.45, -1.4 ],
       [ 2.55, -1.4 ],
       [-0.45, -1.45],
       [-0.4 , -1.45],
       [ 2.55, -1.45],
       [-0.45, -1.5 ],
       [-0.4 , -1.5 ],
       [ 2.6 , -1.5 ],
       [-0.45, -1.55],
       [-0.4 , -1.55],
       [ 2.6 , -1.55],
       [-0.45, -1.6 ],
       [-0.4 , -1.6 ],
       [ 2.6 , -1.6 ],
       [-0.45, -1.65],
       [-0.4 , -1.65],
       [ 2.6 , -1.65],
       [-0.45, -1.7 ],
       [-0.4 , -1.7 ],
       [ 2.6 , -1.7 ],
       [-0.4 , -1.75],
       [ 2.55, -1.75],
       [-0.4 , -1.8 ],
       [ 2.55, -1.8 ],
       [-0.45, -1.85],
       [-0.4 , -1.85],
       [ 2.55, -1.85],
       [-0.45, -1.9 ],
       [-0.4 , -1.9 ],
       [-0.4 , -1.95],
       [-0.4 , -2.  ],
       [-0.35, -2.  ],
       [-0.4 , -2.05],
       [-0.35, -2.05],
       [ 2.5 , -2.05],
       [ 2.55, -2.05],
       [-0.35, -2.1 ],
       [ 2.5 , -2.1 ],
       [ 2.55, -2.1 ],
       [-0.35, -2.15],
       [ 2.5 , -2.15],
       [ 2.55, -2.15],
       [-0.4 , -2.2 ],
       [-0.35, -2.2 ],
       [ 2.5 , -2.2 ],
       [-0.4 , -2.25],
       [-0.35, -2.25],
       [-0.35, -2.3 ],
       [ 2.45, -2.3 ],
       [-0.3 , -2.35],
       [ 2.45, -2.35],
       [-0.3 , -2.4 ],
       [-0.3 , -2.45],
       [-0.2 , -2.6 ],
       [ 2.05, -2.6 ],
       [ 2.2 , -2.6 ],
       [ 2.25, -2.6 ],
       [ 2.1 , -2.65],
       [-0.15, -2.7 ],
       [-0.05, -2.75],
       [ 0.  , -2.75],
       [ 0.05, -2.75],
       [ 0.1 , -2.75],
       [ 0.15, -2.75],
       [-0.05, -2.8 ],
       [ 0.  , -2.8 ],
       [ 0.05, -2.8 ],
       [ 0.1 , -2.8 ],
       [ 1.1 , -2.8 ],
       [ 1.15, -2.8 ],
       [ 1.2 , -2.8 ],
       [ 1.25, -2.8 ],
       [ 1.3 , -2.8 ],
       [ 1.35, -2.8 ],
       [ 1.4 , -2.8 ],
       [ 1.45, -2.8 ],
       [ 1.5 , -2.8 ],
       [ 1.55, -2.8 ],
       [ 1.6 , -2.8 ],
       [ 1.65, -2.8 ],
       [ 1.7 , -2.8 ],
       [ 1.75, -2.8 ],
       [ 1.8 , -2.8 ],
       [ 0.7 , -2.85],
       [ 0.75, -2.85],
       [ 0.8 , -2.85],
       [ 0.85, -2.85],
       [ 0.9 , -2.85],
       [ 0.95, -2.85],
       [ 1.  , -2.85],
       [ 1.05, -2.85]])
here is the visualized dataset:
 However, these are the results I got no matter how I sort my array.
However, these are the results I got no matter how I sort my array.
 

I pinned a few problems about my dataset but don’t know how to deal with them:
- Many x and y values are not one to one
- Points are not sorted in a neighboring order
So if my assumptions are correct, the main question would be how can I sort the array in such an order that the splprep method works? If not, I would really appreciate any solution that helps me solve the problem!
[Update] Thanks to @michael-szczesny ‘s reply I got a satisfying result

Advertisement
Answer
You can translate your data to the origin an sort by the complex angle.
Setup the data
import numpy as np
import matplotlib.pyplot as plt
from scipy.interpolate import splprep, splev
x = np.array(
      [[-0.50, -1.20],
       [-0.50, -1.15],
       [-0.50, -1.10],
       [-0.50, -1.05],
       [-0.50, -1.00],
       [-0.50, -0.95],
       [-0.50, -0.90],
       [-0.50, -0.85],
       [-0.45, -1.90],
       [-0.45, -1.85],
       [-0.45, -1.70],
       [-0.45, -1.65],
       [-0.45, -1.60],
       [-0.45, -1.55],
       [-0.45, -1.50],
       [-0.45, -1.45],
       [-0.45, -1.40],
       [-0.45, -1.35],
       [-0.45, -1.30],
       [-0.45, -1.25],
       [-0.45, -1.20],
       [-0.45, -1.15],
       [-0.45, -1.10],
       [-0.45, -1.05],
       [-0.40, -2.25],
       [-0.40, -2.20],
       [-0.40, -2.05],
       [-0.40, -2.00],
       [-0.40, -1.95],
       [-0.40, -1.90],
       [-0.40, -1.85],
       [-0.40, -1.80],
       [-0.40, -1.75],
       [-0.40, -1.70],
       [-0.40, -1.65],
       [-0.40, -1.60],
       [-0.40, -1.55],
       [-0.40, -1.50],
       [-0.40, -1.45],
       [-0.40, -0.70],
       [-0.40, -0.65],
       [-0.35, -2.30],
       [-0.35, -2.25],
       [-0.35, -2.20],
       [-0.35, -2.15],
       [-0.35, -2.10],
       [-0.35, -2.05],
       [-0.35, -2.00],
       [-0.30, -2.45],
       [-0.30, -2.40],
       [-0.30, -2.35],
       [-0.25, -0.60],
       [-0.20, -2.60],
       [-0.20, -0.60],
       [-0.15, -2.70],
       [-0.15, -0.45],
       [-0.15, -0.40],
       [-0.05, -2.80],
       [-0.05, -2.75],
       [0.00, -2.80],
       [0.00, -2.75],
       [0.00, -0.20],
       [0.00, -0.15],
       [0.00, -0.10],
       [0.05, -2.80],
       [0.05, -2.75],
       [0.05, -0.10],
       [0.10, -2.80],
       [0.10, -2.75],
       [0.15, -2.75],
       [0.30, -0.05],
       [0.35, -0.05],
       [0.40, -0.05],
       [0.45, -0.05],
       [0.50, -0.05],
       [0.55, -0.05],
       [0.60, -0.05],
       [0.65, -0.05],
       [0.70, -2.85],
       [0.70, -0.05],
       [0.75, -2.85],
       [0.75, -0.05],
       [0.80, -2.85],
       [0.80, -0.05],
       [0.85, -2.85],
       [0.85, -0.05],
       [0.90, -2.85],
       [0.90, -0.05],
       [0.95, -2.85],
       [0.95, -0.05],
       [1.00, -2.85],
       [1.00, -0.05],
       [1.05, -2.85],
       [1.05, -0.05],
       [1.10, -2.80],
       [1.10, -0.05],
       [1.15, -2.80],
       [1.15, -0.05],
       [1.20, -2.80],
       [1.20, -0.05],
       [1.25, -2.80],
       [1.25, -0.05],
       [1.30, -2.80],
       [1.30, -0.05],
       [1.35, -2.80],
       [1.35, -0.05],
       [1.40, -2.80],
       [1.40, -0.05],
       [1.45, -2.80],
       [1.45, -0.05],
       [1.50, -2.80],
       [1.50, -0.05],
       [1.55, -2.80],
       [1.55, -0.05],
       [1.60, -2.80],
       [1.60, -0.05],
       [1.65, -2.80],
       [1.65, -0.05],
       [1.70, -2.80],
       [1.70, -0.05],
       [1.75, -2.80],
       [1.75, -0.05],
       [1.80, -2.80],
       [1.80, -0.05],
       [2.05, -2.60],
       [2.10, -2.65],
       [2.10, -0.20],
       [2.10, -0.15],
       [2.15, -0.20],
       [2.15, -0.15],
       [2.20, -2.60],
       [2.20, -0.25],
       [2.20, -0.20],
       [2.25, -2.60],
       [2.35, -0.50],
       [2.35, -0.45],
       [2.35, -0.40],
       [2.35, -0.35],
       [2.40, -0.60],
       [2.40, -0.55],
       [2.40, -0.50],
       [2.40, -0.45],
       [2.45, -2.35],
       [2.45, -2.30],
       [2.45, -0.90],
       [2.45, -0.85],
       [2.45, -0.80],
       [2.45, -0.75],
       [2.45, -0.70],
       [2.45, -0.65],
       [2.45, -0.60],
       [2.50, -2.20],
       [2.50, -2.15],
       [2.50, -2.10],
       [2.50, -2.05],
       [2.50, -1.20],
       [2.50, -1.15],
       [2.50, -1.10],
       [2.50, -1.05],
       [2.50, -1.00],
       [2.50, -0.95],
       [2.50, -0.90],
       [2.50, -0.85],
       [2.50, -0.70],
       [2.55, -2.15],
       [2.55, -2.10],
       [2.55, -2.05],
       [2.55, -1.85],
       [2.55, -1.80],
       [2.55, -1.75],
       [2.55, -1.45],
       [2.55, -1.40],
       [2.55, -1.35],
       [2.55, -1.30],
       [2.55, -1.25],
       [2.55, -1.20],
       [2.55, -1.15],
       [2.55, -1.10],
       [2.60, -1.70],
       [2.60, -1.65],
       [2.60, -1.60],
       [2.60, -1.55],
       [2.60, -1.50]])
Convert your data to complex coordinates with np.angle((xs[:,0] + 1j*xs[:,1])) and use it to sort your data.
xs = (x - x.mean(0)) x_sort = xs[np.angle((xs[:,0] + 1j*xs[:,1])).argsort()]
Now you can plot(code by @rth) your data in the right order.
# plot from https://stackoverflow.com/a/31466013/14277722 as mentioned in the question tck, u = splprep(x_sort.T, u=None, s=0.0, per=1) u_new = np.linspace(u.min(), u.max(), 1000) x_new, y_new = splev(u_new, tck, der=0) plt.figure(figsize=(10,10)) plt.plot(x_sort[:,0], x_sort[:,1], 'ro') plt.plot(x_new, y_new, 'b--');
Out:
 
						