matplotlib - извлечение данных из контурных линий - PullRequest
46 голосов
/ 14 апреля 2011

Я хотел бы получить данные из одного контура равномерно распределенных 2D-данных (данные, подобные изображению).

На основании примера, найденного в похожем вопросе: Как получить значения (x, y) линии, построенной контурным графиком (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()

Результат этого вызова в cs.collections[0].get_paths():

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

Исходя из графиков, этот результат имеет смысл и представляется набором (y, x) пар для контурной линии.

Кроме ручного зацикливания этого возвращаемого значения, извлечения координат и сборки массивов для линии, существуют ли более эффективные способы получения данных из объекта matplotlib.path? Есть ли подводные камни при извлечении данных из matplotlib.path?

В качестве альтернативы, есть ли альтернативы в matplotlib или, что еще лучше, numpy / scipy, чтобы сделать подобное? Идеально было бы получить вектор с высоким разрешением пар (x, y), описывающих линию, который можно было бы использовать для дальнейшего анализа, поскольку в целом мои наборы данных не являются маленькими или простыми, как в примере выше.

Ответы [ 3 ]

45 голосов
/ 14 апреля 2011

За заданный путь вы можете получить очки следующим образом:

p = cs.collections[0].get_paths()[0]
v = p.vertices
x = v[:,0]
y = v[:,1]
9 голосов
/ 04 февраля 2013

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

Пользователи объектов Path не должны получать доступ к массивам вершин и кодов непосредственно. Вместо этого они должны использовать iter_segments (), чтобы получить пары вершина / код. Это важно, так как многие объекты Path, как оптимизация, не хранить коды вообще, но иметь код по умолчанию предоставляется для них функцией iter_segments ().

В противном случае, я не совсем уверен, каков твой вопрос. [Zip] - иногда полезная встроенная функция при работе с координатами. 1

4 голосов
/ 20 мая 2015

Я столкнулся с подобной проблемой и наткнулся на обсуждение этого списка matplotlib .

В принципе, можно убрать построение графиков и напрямую вызывать базовые функции, не очень удобно, но возможно.Решение также не является точным, так как в базовом коде, вероятно, происходит некоторая интерполяция.

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()
...