如何去除FFT图中连接正负频率的多余水平线?
FFT图中正负频率间多余连接线的去除方案
我在展示观测数据趋势及对应FFT图时,FFT图里总是出现一条不需要的水平线。已知这是因为fftfreq生成的频率包含正负值,绘图时会连接最后一个负频率与第一个正频率,但我需要保留正负频率的完整展示,请问怎么去掉这条连接线?
最小可复现代码
import numpy as np from scipy.fft import fft, fftfreq import matplotlib.pyplot as plt observations = np.array([ 3.78998207e-01, 3.05199629e-01, 2.29614343e-01, 1.86568613e-01, 1.83449462e-01, 1.77892746e-01, 1.66237352e-01, 1.81950778e-01, 9.88351226e-02, 1.29674430e-01, 7.08703360e-02, 3.64963487e-02, 2.75641060e-02, 6.21573753e-02, 8.51043646e-02, 5.32184940e-02, 6.47005530e-02, -6.41628893e-02, -1.86618020e-01, -4.08624200e-02, -2.71649960e-02, -8.22041576e-03, 9.13242105e-03, 1.67080717e-01, -1.37465317e-01, 2.74977101e-04, 4.47602122e-02, 8.27649668e-02, -5.60661808e-02, -2.26248880e-01, -1.54768403e-01, -4.46428484e-02, 4.57611677e-02, 9.83215698e-02, 9.22357256e-02, -1.23436114e-01, -2.76981909e-01, -1.98824586e-01, -2.33452893e-01, -2.57550630e-01, -9.13919527e-02, 2.64029442e-02, -5.44394568e-02, 4.02010984e-01, 3.27256645e-01, 2.14259077e-01, 5.08021357e-01, 5.55141121e-01, 6.11203693e-01, 5.34086779e-01, 2.19652659e-01, 1.71635054e-01, 1.30867565e-01, 1.25133212e-01, 1.02010973e-01, 1.16727950e-02, 2.84545455e-02, -1.73553706e-02, -1.33998184e-01, -1.36456573e-01, -1.68706794e-01, -1.28378379e-01, -1.43710423e-01, -2.02454545e-01, -4.30164457e-01, -5.19982175e-01, -3.74452537e-01, -3.64076796e-01, -3.20950700e-01, -2.34052515e-01, -1.37158482e-01, 2.80797054e-02, 7.04379682e-02, 1.13920696e-01, 1.26391389e-01, 9.31688808e-02, 1.46000000e-01, 1.18380338e-01, 5.18909438e-02, 1.11584791e-01, 6.43582617e-02, -6.36856386e-02, -9.16134931e-02, -1.02616820e-01, -4.43179890e-01, -1.28223431e+00, -1.86160058e+00, -1.43772912e+00, -1.21047880e+00, -7.21282278e-01, -1.65349241e-01, 4.58791266e-02, 2.42897190e-01, 3.26587994e-01, 3.15827382e-01, -5.29090909e-02, 8.97887313e-03, 2.61194000e-02, -2.24566234e-01, -9.18572710e-02]) observed_fft = fft(observations) fs = 100 n = observations.size fft_fre = fftfreq(n, d=1/fs) x_time = np.arange(len(observations)) fig, axs = plt.subplots(2) axs[0].plot(x_time, observations) axs[1].plot(fft_fre, np.abs(observed_fft)) plt.show()
问题图示

两种解决方法
方法1:对频率排序后绘图
fftfreq默认输出的频率顺序是[0, 1, ..., n/2-1, -n/2, ..., -1],直接绘图会导致最后一个负频率和第一个正频率被连接。将频率和对应的FFT幅值按频率从小到大排序后再绘制,就能避免跨零的连接线:
# 对频率和FFT幅值按频率排序 sorted_idx = np.argsort(fft_fre) sorted_freq = fft_fre[sorted_idx] sorted_fft_abs = np.abs(observed_fft)[sorted_idx] # 绘制排序后的FFT图 axs[1].plot(sorted_freq, sorted_fft_abs)
方法2:分离正负频率分别绘制
将负频率和正频率(包含0)分成两组,分别调用plot绘制,中间自然断开:
# 分离负频率和非负频率的掩码 neg_mask = fft_fre < 0 pos_mask = fft_fre >= 0 # 分别绘制两部分 axs[1].plot(fft_fre[neg_mask], np.abs(observed_fft)[neg_mask]) axs[1].plot(fft_fre[pos_mask], np.abs(observed_fft)[pos_mask])
两种方法都能保留正负频率的完整展示,同时去掉那条多余的水平线。
内容的提问来源于stack exchange,提问作者Amina Umar
相关产品推荐
相关产品推荐

