我一直试图获得一堆轮廓的周长和区域(我使用水平集方法来模拟固体/混合火箭发动机中的回火)。我采取了这里推荐的方法:
matplotlib - extracting values from contour lines
以下是重现错误的最小示例:
import numpy as np
import pylab as pl
import skfmm
n_pts = 1000
r_f = 98 #mm (final radius)
fin_l = 20 #mm (fin length)
fin_w = 10 #mm (fin length)
#set up grid
X, Y = np.meshgrid(np.linspace(-r_f,r_f,n_pts), np.linspace(-r_f,r_f,n_pts))
initial_grid = -1 * np.ones_like(X)
#set up initial shape
initial_grid[np.logical_and(np.abs(Y) < fin_l, np.abs(X) < fin_w/2.)] = 1
initial_grid[np.logical_and(np.abs(Y) < fin_w/2., np.abs(X) < fin_l)] = 1
#obtain 3D Array
contour_grid = skfmm.distance(initial_grid, dx=1e-2)
perims = np.array([])
webs = np.linspace(0, r_f, n_pts/10)
for web in webs:
web_ctr = pl.contour(X, Y, contour_grid, [web])
no_error_here = p = web_ctr.collections[0].get_paths()
out_of_range_error = web_ctr.collections[0].get_paths()[0]
我收到“列表索引超出范围”错误,结果是no_error_here
是一个空列表。我环顾四周,我发现matplotlib没有任何理由这样做。提示?
答案 0 :(得分:1)
基本上,如果勾勒出数据范围之外的值,contour
将返回一个空集合。
检查您的轮廓值是否在数据范围内,或检查是否有空集合。
此外,您目前假设在给定值下只有一个轮廓。这可能是一个糟糕的假设。因为您正在构建单个值,所以您确实想要使用collections[0]
,但该轮廓可能有多个路径。
如果您不想绘制结果,为什么不直接提取轮廓值? skimage.measure.find_contours
听起来更适合你正在做的事情。
例如:
import numpy as np
from skimage.measure import find_contours
data = np.random.random((10,10))
contours = find_contours(data, 0.5)
for xy in contours:
x, y = xy.T
perim = np.hypot(np.diff(x), np.diff(y)).sum()