Trazar un conjunto de puntos dados para formar una curva cerrada en matplotlib

Tengo (toneladas de) coordenadas de puntos para curvas cerradas ordenadas en orden creciente x.

Cuando lo graficamos de manera regular, el resultado que obtengo es este:

(circule solo como ejemplo, las formas que tengo actualmente pueden, en el mejor de los casos, clasificarse como ameboids) introduzca la descripción de la imagen aquí

Pero el resultado que estoy buscando es algo como esto: introduzca la descripción de la imagen aquí

He mirado a través de matplotlib y no pude encontrar nada. (Tal vez tenía mis palabras clave mal …?)

He intentado reformatear los datos de las siguientes maneras:

  1. Elija un punto al azar, encuentre su vecino más cercano y luego el vecino más cercano y así sucesivamente. Falla en los bordes donde, a veces, los datos no son muy consistentes (el vecino más cercano puede estar en el lado opuesto de la curva).

  2. Para tener en cuenta los datos inconsistentes, traté de comprobar si la pendiente entre dos puntos (que se consideran vecinos más cercanos) coincide con la pendiente conectada anteriormente: falla, por razones que no pude encontrar. (Pasó un número considerable de horas antes de que me di por vencido)

  3. Elija x_minimum y x_maximum (y las correspondientes coordenadas y) y dibuje una línea imaginaria y ordene por puntos a cada lado de la línea. – Falla cuando tienes una curva que parece un plátano.

¿Hay algún paquete / biblioteca de python que pueda ayudarme a llegar a donde quiero? ¿O puede ayudarme con ideas para ordenar mejor mis puntos de datos? Gracias por adelantado.

EDITAR:

Probé el Casco cóncavo en el círculo que tenía, alguna idea de por qué las líneas se superponen en algunos lugares. Aquí está la imagen: introduzca la descripción de la imagen aquí

EDIT2: El problema se resolvió cambiando parte de mi código según lo sugerido por @Reblochon Masque en la sección de comentarios de su respuesta.

Si no sabes cómo están configurados tus puntos (si lo haces, te recomiendo que sigas ese orden, será más rápido) puedes usar Convex Hull desde scipy:

import matplotlib.pyplot as plt from scipy.spatial import ConvexHull # RANDOM DATA x = np.random.normal(0,1,100) y = np.random.normal(0,1,100) xy = np.hstack((x[:,np.newaxis],y[:,np.newaxis])) # PERFORM CONVEX HULL hull = ConvexHull(xy) # PLOT THE RESULTS plt.scatter(x,y) plt.plot(x[hull.vertices], y[hull.vertices]) plt.show() 

, que en el ejemplo anterior resulta esto:

Casco convexo en una parcela.

Tenga en cuenta que este método creará un cuadro delimitador para sus puntos.

Aquí hay un ejemplo que quizás haga lo que quiera y resuelva su problema: más información aquí

 import numpy as np import matplotlib.pyplot as plt from scipy.spatial import ConvexHull points = np.random.rand(30, 2) # 30 random points in 2-D hull = ConvexHull(points) #xs = np.array([point[0] for point in points]) #ys = np.array([point[1] for point in points]) #xh = np.array([point[0] for point in hull.points]) #yh = np.array([point[1] for point in hull.points]) plt.plot(points[:,0], points[:,1], 'o') for simplex in hull.simplices: plt.plot(points[simplex, 0], points[simplex, 1], 'k-') plt.plot(points[hull.vertices,0], points[hull.vertices,1], 'r--', lw=2) plt.plot(points[hull.vertices[0],0], points[hull.vertices[0],1], 'ro') plt.show() 

Los puntos en el casco convexo se trazan por separado y se unen para formar un polígono. Puedes manipularlos más si quieres.

introduzca la descripción de la imagen aquí

Creo que esta es quizás una buena solución (fácil y barata) para implementar en su caso. Funcionará bien si sus formas son convexas.

En caso de que sus formas no sean todas convexas, un enfoque que podría ser exitoso podría ser ordenar los puntos según el vecino más cercano y dibujar un polígono de este conjunto ordenado.