matplotlib – extrayendo datos de curvas de nivel

Me gustaría obtener datos de un solo contorno de datos 2D espaciados uniformemente (datos similares a una imagen).

Basado en el ejemplo encontrado en una pregunta similar: ¿Cómo puedo obtener los valores (x, y) de la línea que está trazada por un gráfico de contorno (matplotlib)?

>>> import matplotlib.pyplot as plt >>> x = [1,2,3,4] >>> y = [1,2,3,4] >>> m = [[15,14,13,12],[14,12,10,8],[13,10,7,4],[12,8,4,0]] >>> cs = plt.contour(x,y,m, [9.5]) >>> cs.collections[0].get_paths() 

El resultado de esta llamada a cs.collections[0].get_paths() es:

 [Path([[ 4. 1.625 ] [ 3.25 2. ] [ 3. 2.16666667] [ 2.16666667 3. ] [ 2. 3.25 ] [ 1.625 4. ]], None)] 

Basado en los gráficos, este resultado tiene sentido y parece ser una colección de (y, x) pares para la línea de contorno.

Además del bucle manual sobre este valor de retorno, la extracción de coordenadas y el ensamblaje de matrices para la línea, ¿hay mejores maneras de recuperar datos de un objeto matplotlib.path ? ¿Hay inconvenientes a tener en cuenta al extraer datos de un matplotlib.path ?

Alternativamente, ¿hay alternativas dentro de matplotlib o, mejor aún, numpy o hacer algo similar? Lo ideal sería obtener un vector de alta resolución de (x, y) pares que describa la línea, que podría usarse para un análisis más detallado, ya que, en general, mis conjuntos de datos no son tan pequeños o simples como el ejemplo anterior.

Para un camino dado, puedes obtener los puntos como este:

 p = cs.collections[0].get_paths()[0] v = p.vertices x = v[:,0] y = v[:,1] 

de: http://matplotlib.org/api/path_api.html#module-matplotlib.path

Los usuarios de objetos de ruta no deben acceder a los vértices y códigos de matrices directamente. En su lugar, deberían usar iter_segments () para obtener los pares de vértice / código. Esto es importante, ya que muchos objetos de Ruta, como optimización, no almacenan códigos en absoluto, sino que tienen uno predeterminado proporcionado por iter_segments ().

De lo contrario, no estoy realmente seguro de cuál es tu pregunta. [Zip] es una función incorporada a veces útil cuando se trabaja con coordenadas. 1

Me enfrento a un problema similar y tropecé con esta discusión de la lista de matplotlib .

Básicamente, es posible eliminar el trazado y llamar directamente a las funciones subyacentes, no muy conveniente, pero posible. La solución tampoco tiene una precisión de píxeles, ya que probablemente exista alguna interpolación en el código subyacente.

 import matplotlib.pyplot as plt import matplotlib._cntr as cntr import scipy as sp data = sp.zeros((6,6)) data[2:4,2:4] = 1 plt.imshow(data,interpolation='none') level=0.5 X,Y = sp.meshgrid(sp.arange(data.shape[0]),sp.arange(data.shape[1])) c = cntr.Cntr(X, Y, data.T) nlist = c.trace(level, level, 0) segs = nlist[:len(nlist)//2] for seg in segs: plt.plot(seg[:,0],seg[:,1],color='white') plt.show()