【问题标题】:Adjust xrange depending on where signal is根据信号的位置调整 xrange
【发布时间】:2021-11-23 18:09:04
【问题描述】:

假设我有一个数据流,为简单起见,将其设为贝尔曲线,从大范围获取:

import numpy as np
import matplotlib.pyplot as plt


def pdf(x, mean, std):
    """Return a PDF."""
    y_out = 1/(std * np.sqrt(2 * np.pi)) * np.exp(-(x - mean)**2 / (2 * std**2))
    return y_out


x = np.linspace(-1000, 1000, 20000)
y = 100 * pdf(x, 0, 1) + np.random.normal(0, 1, 20000)

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

由于 x 范围太大,绘图将只显示一条非常窄的线,而且我们不需要在绘图中包含所有噪声。

在这种情况下,通过仅显示范围 [-20, 20] 来绘制它可能是有意义的,例如:ax.set_xlim([-20, 20])。 但是,假设现在我们从另一次收购中得到了类似的东西:

y = 100 * pdf(x, -50, 1) + 100 * pdf(x, 0, 1) + 100 * pdf(x, 40, 1) + np.random.normal(0, 1, 20000)

有了这样一个函数,我们可能想要绘制更大的范围,例如ax.set_xlim([-70, 60]),将采集到的所有信号可视化。

有没有办法根据实际信号(即任何高于某个阈值,比如 10)以编程方式调整限制,而不必先绘制整个范围,然后手动调整?

【问题讨论】:

  • 您是否提前知道信号中峰值的位置,或者您是在问我们如何进行信号分析?

标签: python matplotlib plot


【解决方案1】:

使用argwhere 获取y 高于某个阈值的索引,例如np.argwhere(y > 10)。在实践中,您可能希望在两侧添加一些边距,例如 200 点:

import numpy as np
import matplotlib.pyplot as plt

def pdf(x, mean, std):
    """Return a PDF."""
    y_out = 1/(std * np.sqrt(2 * np.pi)) * np.exp(-(x - mean)**2 / (2 * std**2))
    return y_out


x = np.linspace(-1000, 1000, 20000)
y = [100 * pdf(x, 0, 1) + np.random.normal(0, 1, 20000),
     100 * pdf(x, -50, 1) + 100 * pdf(x, 0, 1) + 100 * pdf(x, 40, 1) + np.random.normal(0, 1, 20000)]


def get_lims(y, threshold=10, margin=200):
    """Get indices +/- margin where y is above threshold."""
    signal = np.argwhere(y > threshold).flatten()
    return np.clip((signal[0] - margin, signal[-1] + margin), 0, len(y)-1)

fig, ax = plt.subplots(nrows=2)
for i in range(2):
    ax[i].plot(x, y[i])
    ax[i].set_xlim(x[get_lims(y[i])])

【讨论】:

    【解决方案2】:

    与 Stef 的答案非常相似,只是我提出了最小宽度和额外百分比,因此边距将取决于您要显示的 x 的数量,而不是边距,因此您可以调整 window_excessmin_width。如果你有很多情节要制作,这样的事情可能会很有用。用这个替换 Stef 的 get_lims 函数将达到结果:

    def get_lims(y, threshold = 10, window_excess = 0.5, min_width = 100):
        minwidth = min_width / (1 + window_excess)
    
        a = np.argwhere(y > threshold)
        
        da = max(minwidth, x[a[-1]] - x[a[0]])
        ma = (x[a[-1]] + x[a[0]]) / 2
        minx = ma - da * (1 + window_excess) / 2
        maxx = ma + da * (1 + window_excess) / 2
        return([minx, maxx])
    

    您只需要检查xminxmax 是否在x 范围内。

    【讨论】:

      猜你喜欢
      • 2018-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-03-23
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多