Ответ 1
Для данного пути вы можете получить такие точки:
p = cs.collections[0].get_paths()[0]
v = p.vertices
x = v[:,0]
y = v[:,1]
Я хотел бы получить данные из одного контура равномерно распределенных 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), описывающих линию, которые могут быть использованы для дальнейшего анализа, поскольку, как правило, мои наборы данных не являются небольшими или простыми, как пример выше.
Для данного пути вы можете получить такие точки:
p = cs.collections[0].get_paths()[0]
v = p.vertices
x = v[:,0]
y = v[:,1]
from: http://matplotlib.org/api/path_api.html#module-matplotlib.path
Пользователи объектов Path не должны обращаться к массивам вершин и кодов непосредственно. Вместо этого они должны использовать iter_segments(), чтобы получить пары вершин/кодов. Это важно, поскольку многие объекты Path, как оптимизация, не сохраняют коды вообще, но имеют значение по умолчанию предоставленные для них iter_segments().
В противном случае я не уверен, в чем ваш вопрос. [Zip] - иногда полезная встроенная функция при работе с координатами. 1
Я столкнулся с аналогичной проблемой и наткнулся на это обсуждение списка матплотбликов.
В принципе, можно отбросить график и вызвать базовые функции напрямую, а не супер удобно, но возможно. Решение также не является точным пикселем, так как, вероятно, в базовом коде происходит некоторая интерполяция.
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()
Вершины всех путей могут быть возвращены в виде массива float64 просто через:
cs.allsegs[i][j] # for element j, in level i
Подробнее...
Просматривать коллекции и извлекать пути и вершины - не самая прямая и самая быстрая вещь. Возвращенный объект Contour фактически имеет атрибуты для сегментов с помощью cs.allsegs
, который возвращает вложенный список формы [уровень] [элемент] [vertex_coord]:
num_levels = len(cs.allsegs)
num_element = len(cs.allsegs[0]) # in level 0
num_vertices = len(cs.allsegs[0][0]) # of element 0, in level 0
num_coord = len(cs.allsegs[0][0][0]) # of vertex 0, in element 0, in level 0
См. ссылку:https://matplotlib.org/3.1.1/api/contour_api.html