如何调整spectrogram的x轴偏移以准确展示起始时间为-1秒的信号
问题描述
我有一段起始时间为-1秒的信号,在绘制spectrogram时,第一个bin的边缘从0开始(中点在0.25处),请问如何调整x轴以准确呈现数据?
我尝试使用xextent=(time[0] + 0.125, time[-1])暂时解决了问题,但不清楚bin宽度由什么变量决定,担心该参数在采样率、点数不同的其他数据集上不通用,请问该如何实现通用化配置?
原始示例代码
import numpy as np import matplotlib.pyplot as plt import signal time = np.linspace(-1, 16, 65536) signal = np.sin(2 * np.pi * time) fig = plt.figure() ax_top = fig.add_subplot(211) ax_spec = fig.add_subplot(212) ax_top.plot(time, signal) ax_top.set_xlim(-1, 10) ax_spec.set_xlim(-1, 10) Pxx, freqs, bins, cax = ax_spec.specgram(signal, NFFT=2048, Fs=4096, noverlap=2048 / 2, mode='magnitude', pad_to=2048 * 16) ax_spec.set_xticks(np.arange(time[0], time[-1], 1)) ax_top.set_xticks(np.arange(time[0], time[-1], 1)) plt.show()
解决方法
核心原理
你之前手动加的0.125是当前参数下时间bin半宽的硬编码值,该值由三个参数共同决定:
- FFT窗长度
NFFT - 窗重叠点数
noverlap - 采样率
Fs
时间bin的步长计算公式为:dt_bin = (NFFT - noverlap) / Fs
你当前参数下计算得(2048-1024)/4096 = 0.25s,半宽就是0.125,这是临时方案生效的原因。
通用化配置方案
不需要硬编码任何偏移值,直接复用specgram方法返回的bins变量(该变量存储了默认零起始时间下每个时间bin的中点),加上你信号的实际起始时间偏移即可完成对齐,同时自动适配任意NFFT、重叠率、采样率参数。
修正后代码
import numpy as np import matplotlib.pyplot as plt # 注意:不要将标准库signal作为变量名,避免命名冲突 import signal as sig_lib time = np.linspace(-1, 16, 65536) sig = np.sin(2 * np.pi * time) t_start = time[0] fig = plt.figure() ax_top = fig.add_subplot(211) ax_spec = fig.add_subplot(212) ax_top.plot(time, sig) ax_top.set_xlim(-1, 10) ax_spec.set_xlim(-1, 10) Pxx, freqs, bins, cax = ax_spec.specgram( sig, NFFT=2048, Fs=4096, noverlap=2048/2, mode='magnitude', pad_to=2048*16 ) # 计算真实时间对应的bin范围 dt_bin = bins[1] - bins[0] real_x_min = t_start + bins[0] - dt_bin/2 real_x_max = t_start + bins[-1] + dt_bin/2 # 动态设置xextent cax.set_extent([real_x_min, real_x_max, freqs[0], freqs[-1]]) ax_spec.set_xticks(np.arange(time[0], time[-1], 1)) ax_top.set_xticks(np.arange(time[0], time[-1], 1)) plt.show()
验证效果
运行后频谱图的时间轴会和上方波形的时间轴完全对齐,第一个bin的位置会匹配信号实际的起始时间,无需手动调整偏移值。
内容的提问来源于stack exchange,提问作者Morgs
相关产品推荐
相关产品推荐

