获取数组中范围的开始和结束

时间:2018-10-03 11:24:43

标签: python arrays numpy matplotlib

假设我有一个信号,例如正弦波:

x = np.arange(100)
y = np.sin(x/10)

在绘制此图形时,我要用红色突出显示y的值高于某个阈值的区域,例如0.7。我想做这样的事情

region = [i for i, e in enumerate(y) if e >= 0.7]
fig, ax = plt.subplots()
ax.plot(x, y)

k = region [0]
for i in region:
    if i-k == 1:
       ax.axvspan(k, i+1, facecolor='red', alpha=0.2)
    k = i

plt.show()

添加+1的原因是我要在突出显示的区域中“包括”最后一点。

但是,这会生成重叠的axvspan,这意味着第一个和最后一个将“更轻”(因为我使用的是alpha = 0.2),如图所示: Plot

还有另一种(可能更简单)的方法来实现这一目标吗?

1 个答案:

答案 0 :(得分:1)

一种方法是在y上使用掩码,以查找值超出阈值的位置。然后,您需要找到掩码的值为True的第一个和最后一个出现。这可以通过使用this question的答案来找到True-FalseFalse-True过渡来完成:

x = np.arange(100)
y = np.sin(x/10)

fig, ax = plt.subplots()
ax.plot(x, y)

mask = y >= 0.7

first_vals = np.argwhere((~mask[:-1] & mask[1:]))  # Look for False-True transitions
last_vals = np.argwhere((mask[:-1] & ~mask[1:])) + 1  # Look for True-False transitions

for start, stop in zip(first_vals, last_vals):
    ax.axvspan(start, stop, facecolor='red', alpha=0.2)

plt.show()

enter image description here

引入第二个条件意味着您将必须使用numpy.logical_or。如果掩码的第一个值为True,则可能需要进行一些额外的检查:

mask = np.logical_or(y>0.7, y==0)

if mask[0]:
    first_vals = np.argwhere((~mask[:-1] & mask[1:]))  # Look for False-True transitions
    last_vals = np.argwhere((mask[:-1] & ~mask[1:])) + 1 # Look for True-False transitions
    first_vals = np.insert(first_vals, 0, 0, axis=0)

for start, stop in zip(first_vals, last_vals):
    ax.axvspan(start, stop, facecolor='red', alpha=0.2)

enter image description here