)
信号分析入门如何用Python快速绘制时域、频域和时频域图附完整代码信号分析是工程和科研中不可或缺的技能无论是故障诊断、音频处理还是生物医学研究都离不开对信号特性的深入理解。本文将带您用Python从零开始掌握信号分析的三大核心领域时域、频域和时频域分析。无需复杂理论推导我们将通过直观的代码示例和可视化结果让您快速上手实际应用。1. 环境准备与基础概念在开始之前我们需要配置Python环境并安装必要的库。推荐使用Anaconda创建独立环境conda create -n signal_analysis python3.9 conda activate signal_analysis pip install numpy matplotlib scipy信号分析的三个维度时域分析观察信号随时间变化的原始形态频域分析揭示信号包含的频率成分时频分析同时捕捉频率随时间的变化规律提示本文所有代码示例都基于Jupyter Notebook环境测试通过建议边阅读边实践2. 时域分析实战时域分析是最直观的信号观察方式。让我们首先生成一个模拟信号import numpy as np import matplotlib.pyplot as plt # 生成时间序列 fs 1000 # 采样率1000Hz t np.linspace(0, 1, fs, endpointFalse) # 1秒时长 # 创建复合信号50Hz正弦波 120Hz正弦波 随机噪声 signal 0.7 * np.sin(2 * np.pi * 50 * t) \ 0.3 * np.sin(2 * np.pi * 120 * t) \ 0.1 * np.random.randn(len(t)) # 绘制时域图 plt.figure(figsize(10, 4)) plt.plot(t, signal) plt.title(时域信号) plt.xlabel(时间 (s)) plt.ylabel(幅值) plt.grid(True) plt.show()时域图能告诉我们什么信号的幅度变化范围是否存在明显的周期性噪声的严重程度异常脉冲出现的位置3. 频域分析技术频域分析通过傅里叶变换将信号分解为不同频率成分。使用SciPy库可以轻松实现from scipy.fft import fft, fftfreq # 计算FFT n len(signal) yf fft(signal) xf fftfreq(n, 1/fs)[:n//2] # 绘制频谱图 plt.figure(figsize(10, 4)) plt.plot(xf, 2/n * np.abs(yf[0:n//2])) plt.title(频域分析) plt.xlabel(频率 (Hz)) plt.ylabel(幅值) plt.grid(True) plt.xlim(0, 200) # 聚焦0-200Hz范围 plt.show()关键参数对比参数说明典型值采样率(fs)每秒采样点数≥2倍最高频率FFT点数(n)频率分辨率通常取信号长度频率范围显示范围0~fs/24. 时频联合分析对于非平稳信号我们需要同时观察时间和频率的变化。短时傅里叶变换(STFT)是常用方法from scipy.signal import stft # 生成频率变化的信号 chirp_signal np.sin(2 * np.pi * 50 * t**2) # 计算STFT f, t_stft, Zxx stft(chirp_signal, fsfs, nperseg256) # 绘制时频图 plt.figure(figsize(10, 5)) plt.pcolormesh(t_stft, f, np.abs(Zxx), shadinggouraud) plt.title(时频分析 (STFT)) plt.xlabel(时间 (s)) plt.ylabel(频率 (Hz)) plt.colorbar(label幅值) plt.show()STFT参数选择指南nperseg窗口长度影响时间/频率分辨率noverlap重叠样本数通常取75%window窗函数类型如hann5. 综合应用案例轴承故障检测让我们模拟一个工业场景中的轴承振动信号分析# 模拟轴承故障信号 bearing_signal np.sin(2*np.pi*30*t) 0.5*np.sin(2*np.pi*120*t) * (t0.5) # 完整分析流程 fig, (ax1, ax2, ax3) plt.subplots(3, 1, figsize(12, 8)) # 时域图 ax1.plot(t, bearing_signal) ax1.set_title(时域信号) ax1.set_xlabel(时间 (s)) # 频域图 yf fft(bearing_signal) ax2.plot(xf, 2/n * np.abs(yf[0:n//2])) ax2.set_title(频域分析) ax2.set_xlim(0, 200) # 时频图 f, t_stft, Zxx stft(bearing_signal, fsfs) ax3.pcolormesh(t_stft, f, np.abs(Zxx), shadinggouraud) ax3.set_title(时频分析) plt.tight_layout() plt.show()故障特征解读时域图中0.5秒后振幅明显增大频域图显示30Hz基频和120Hz谐波时频图清晰显示故障发生时刻和频率成分变化6. 高级技巧与优化建议提升分析质量的实用技巧预处理很重要# 去趋势处理 from scipy.signal import detrend clean_signal detrend(signal) # 带通滤波 from scipy.signal import butter, filtfilt b, a butter(4, [40, 150], bandpass, fsfs) filtered filtfilt(b, a, signal)选择合适的窗函数# 比较不同窗函数的影响 windows [boxcar, hann, hamming, blackman] plt.figure(figsize(12, 8)) for i, window in enumerate(windows): f, t_stft, Zxx stft(signal, fsfs, windowwindow) plt.subplot(2, 2, i1) plt.pcolormesh(t_stft, f, np.abs(Zxx), shadinggouraud) plt.title(fWindow: {window})自动化特征提取# 提取主要频率成分 peaks_idx np.argsort(np.abs(yf[0:n//2]))[-3:] main_freqs xf[peaks_idx] print(f主要频率成分{main_freqs}Hz)在实际项目中我发现结合时频分析和机器学习能显著提升故障检测准确率。例如将STFT结果作为特征输入到分类模型中比单独使用时域或频域特征效果更好。