Fabian
Fabian

Reputation: 434

Python Pcolormesh not showing

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()

enter image description here

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()

enter image description here

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()

enter image description here

so it should theoretically also print the positive part. What am I missing?

Any help is appreciated Thanks :)

Upvotes: 0

Views: 815

Answers (1)

S_Bersier
S_Bersier

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

Related Questions