Python 获取数组中范围的开始和结束
假设我有一个信号,比如说,一个正弦波:Python 获取数组中范围的开始和结束,python,arrays,numpy,matplotlib,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
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
s,这意味着第一个和最后一个将“更轻”(因为我使用的是alpha=0.2
),如图所示:
是否有另一种(可能更简单的)方法来实现这一点?一种方法是在
y
上应用掩码,以查找值高于阈值的位置。然后,您需要找到掩码值为True
的第一个和最后一个匹配项。这可以通过使用以下答案查找True-False
和False-True
转换来实现:
引入第二个条件意味着您必须使用numpy.logical\u或
。如果掩码的第一个值为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)
如果比较您的体形和OP体形右侧边缘的x值,您会发现两个面片的右侧都缺少一个薄片(薄)。如果OP将ax.axvspan(k,i+1,facecolor='red',alpha=0.2)替换为
ax.axvspan(k,i,facecolor='red',alpha=0.2)
,那么这正是OP得到的结果。也许您应该使用>=0.7
@DavidG这似乎是正确的方法。现在我想添加另一个区域,但是如果我写mask=(y>=0.7)或(y==0)
我会得到ValueError:一个包含多个元素的数组的真值是不明确的。使用a.any()或a.all()
@Enzo我已经更新了答案,看看这是否对你有帮助?@DavidG这正是我想要的。非常感谢。虽然在你的答案中只找到了一个带零的区域,但我假设这是因为x不是精确的n*pi
,因此y不会精确地为零,对吗?@Enzo-Yep是的,第二个“接近零”区域的最接近的y值是0.02,然后是-0.07,所以它没有捕捉到它们。您可能必须指定一些边界才能使值接近零
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)