Matlab转Python:Scipy频谱图与原结果不符问题求助
解决Matlab与Scipy频谱图迁移的差异问题
核心问题分析
你遇到的差异来自三个关键参数和逻辑的不一致:
- Scipy默认返回功率谱密度(实数),而Matlab默认返回复频谱(复数)
- 幅值转dB的计算逻辑存在差异
- 绘图坐标轴方向与Matlab不匹配
具体修正步骤
1. 调整Spectrogram参数,获取复频谱
将Scipy的mode参数改为'complex',同时把scaling设为'spectrum',匹配Matlab的幅值谱输出逻辑:
f, t, Sxx = signal.spectrogram( data[:,0], # 取单声道,对应Matlab的sound(:,1) fs=48000, window='hamming', nperseg=1000, noverlap=500, nfft=1000, detrend='constant', return_onesided=True, scaling='spectrum', # 对应Matlab的幅值谱模式 axis=-1, mode='complex' # 关键:获取复频谱,匹配Matlab返回的S )
2. 修正dB转换逻辑
Matlab的mag2db(abs(S))本质是20*log10(abs(S)),直接用numpy实现该逻辑,避免第三方库的默认参数差异:
# 与Matlab mag2db(abs(S))完全一致的dB计算 dB = 20 * np.log10(np.abs(Sxx)) # 若需对齐录音设备的0dB基准(最大幅值对应0dB),可添加: # dB = dB - np.max(dB)
3. 匹配坐标轴方向
Matlab的axis xy将频率轴原点放在左下角,而Matplotlib默认倒置,需手动反转y轴:
plt.gca().invert_yaxis() # 对应Matlab的axis xy设置
完整修正后的Python代码
import numpy as np from scipy.io import wavfile from scipy import signal import matplotlib.pyplot as plt rate, data = wavfile.read(file) # 匹配Matlab参数获取复频谱 f, t, Sxx = signal.spectrogram( data[:,0], fs=48000, window='hamming', nperseg=1000, noverlap=500, nfft=1000, detrend='constant', return_onesided=True, scaling='spectrum', axis=-1, mode='complex' ) # 计算dB值 dB = 20 * np.log10(np.abs(Sxx)) # 对齐设备0dB基准(可选) # dB = dB - np.max(dB) # 绘图 plt.pcolormesh(t, f, dB, shading='gouraud') plt.ylabel('Frequency (Hz)') plt.xlabel('Time (s)') plt.colorbar() plt.title(f"{file} Spectrogram") plt.gca().invert_yaxis() plt.show()
关键差异说明
- mode参数:Scipy默认
mode='psd'返回功率谱(实数),Matlab默认返回复频谱,必须指定mode='complex'才能匹配 - scaling参数:
'spectrum'对应幅值谱,'density'是功率谱密度,两者幅值量级差异极大 - 坐标轴方向:Matplotlib默认频率轴从上到下为高频到低频,与Matlab相反,需反转y轴
内容的提问来源于stack exchange,提问作者jukebox41188
相关产品推荐
相关产品推荐

