Reputation: 434
I am somewhat lost to what's happening here:
I have got this function that simulates a complex wireless microphone signal
def mic_sig(N, fs, fc, fm, fd):
t = np.arange(N) / fs
x = np.exp(1.j*(2.*np.pi*fc*t + fd/fm*np.sin(2.*np.pi*fm*t)))
return x
I am generating two signals sampled at 6Mhz which are both shifted by 1Mhz from the center frequency
N = int(np.power(2., np.ceil(np.log2(1e5))))
fs = int(1e6)
fm = int(3.9e3)
fd = int(15e3)
fc = int(-1e5)
sig = mic_sig(N, fs=fs, fc=fc, fm=fm, fd=fd)
fc = int(1e5)
sig += mic_sig(N, fs=fs, fc=fc, fm=fm, fd=fd)
Plotting the spectrogram gives exactly what I am expecting:
f1, Pxx_den = signal.welch(sig, fs, nperseg=1024)
plt.plot(f1, Pxx_den)
plt.xlabel('Frequency [Hz]')
plt.ylabel('PSD')
plt.show()
But when I do a STFT with pcolormesh I only get the negative part
f, t, Zxx = signal.stft(sig, fs, window='hann', nperseg=1024)
plt.pcolormesh(t, f, np.abs(Zxx*np.conj(Zxx)), shading='gouraud')
plt.title('STFT Magnitude')
plt.ylabel('Frequency [Hz]')
plt.xlabel('Time [sec]')
plt.show()
and I don't understand why?
Here is what the data after the STFT looks like
plt.plot(np.abs(Zxx*np.conj(Zxx)))
plt.show()
so it should theoretically also print the positive part. What am I missing?
Any help is appreciated Thanks :)
Upvotes: 0
Views: 815
Reputation: 1146
The problem is that stft returns a non-monotonic "f" vector. The solution:
f, t, Zxx = signal.stft(sig, fs, window='hann', nperseg=1024)
ind=np.argsort(f) # returns the indices of the sorted f vector
f=f[ind]
Zxx=Zxx[ind,:]
plt.pcolormesh(t, f, np.abs(Zxx*np.conj(Zxx)), shading='gouraud')
Upvotes: 2