Matlab 频谱图到 matplotlib 频谱

问题描述 投票:0回答:1

我尝试将使用频谱图函数的 matlab 脚本转换为 matplot lib 频谱函数。 一旦转换为频谱图灰度图像,输出图像相似,但功率谱密度矩阵形状不同

Matlab代码:

[~,~,~,P] = spectrogram(X, Fs/N, 0, N, Fs, 'centered');
和: 频谱图(x,窗口,noverlap,nfft,频谱类型) FS = 50 * 10 ** 6 nfft = 500

在这种情况下,P 的形状是 500 x 500

Python代码:

P, freq , t, img = plt.specgram(x, NFFT=nfft , Fs=Fs, Fc=Fc, noverlap=0, window = np.hanning(nfft ))

在这种情况下,P 的形状是 500 x 100000

看起来 matlab 中的窗口参数允许将信号分成段,并且与 plt.specgram 的窗口参数无关(实际上按照文档;))

我的问题是:如何使用 plt.specgram 生成 500x500 矩阵? 有什么想法吗? 谢谢!

python matlab matplotlib
1个回答
0
投票

在 MATLAB 中 - 我们通过窗口大小和重叠显式定义段数。

spectrogram(x, windowSize, overlap, nfft, Fs, 'yaxis');

在 python 中 - 段数由输入信号的长度和 NFFT 参数决定

以此为参考...我们需要调整输入信号长度和 NFFT 参数。

Fs = 50 * 10**6  
N = 500  
desired_segments = 500  

f, t, Sxx = signal.spectrogram(x, fs=Fs, nperseg=N, noverlap=0, nfft=N, 
                                   return_onesided=False, scaling='density')

最终代码

import numpy as np
import matplotlib.pyplot as plt
from scipy import signal


Fs = 50 * 10**6  
N = 500  
desired_segments = 500  


t = np.linspace(0, 1, Fs, endpoint=False)
x = np.sin(2*np.pi*1e6*t) + 0.5*np.sin(2*np.pi*2e6*t)


signal_length = N * desired_segments


if len(x) > signal_length:
    x = x[:signal_length]
else:
    x = np.pad(x, (0, signal_length - len(x)), mode='constant')


f, t, Sxx = signal.spectrogram(x, fs=Fs, nperseg=N, noverlap=0, nfft=N, 
                               return_onesided=False, scaling='density')


Sxx = np.fft.fftshift(Sxx, axes=0)
f = np.fft.fftshift(f)


plt.figure(figsize=(10, 8))
plt.pcolormesh(t, f, 10 * np.log10(Sxx), shading='gouraud')
plt.ylabel('Frequency [Hz]')
plt.xlabel('Time [sec]')
plt.title('Spectrogram')
plt.colorbar(label='Power/Frequency [dB/Hz]')
plt.show()

输出 enter image description here

© www.soinside.com 2019 - 2024. All rights reserved.