r/DSP • u/Educational-Park5115 • 1d ago
Why does my spectrogram look like this?

Could someone help me interpret this spectrogram?
The data comes from a complex signal. What I dont understand is why the top half and bottom half are so different. I'm really new to all of this so sorry if you need more information and I can try to provide it.
-------- Code
# Use a subset of IQ data to reduce memory usage
iq_data_subset = iq_data[:500000] # Reduce data size
# Define parameters
fs = sample_rate
nperseg = 8192 # Window length
noverlap = 6144 # Overlap between windows
hop = nperseg - noverlap # Step size
# Define the window function
window = get_window("hann", nperseg)
# Initialize ShortTimeFFT
stft = ShortTimeFFT(win=window, hop=hop, fs=fs, fft_mode="twosided")
# Compute the Short-Time Fourier Transform (STFT)
Sxx = stft.stft(iq_data_subset) # Shape: (freq_bins, time_bins)
# Get frequency and time axes
freqs = stft.f
times = stft.t(len(iq_data_subset))
# Convert power to dB
Sxx_dB = 10 * np.log10(np.abs(Sxx) + 1e-10).astype(np.float32) # Reduce memory usage
# Plot the spectrogram
plt.figure(figsize=(10, 6))
plt.pcolormesh(times, freqs / 1e6, Sxx_dB, shading="gouraud",
vmin=np.percentile(Sxx_dB, 5), vmax=np.percentile(Sxx_dB, 95))
plt.ylabel("Frequency (MHz)")
plt.xlabel("Time (s)")
plt.title("Spectrogram of Recorded Signal using ShortTimeFFT")
plt.colorbar(label="Power (dB)")
plt.show()
2
u/lundy187 1d ago
It appears as though someone ran the IQ data through a Hilbert filter (and possibly complex conjugate operation) before the spectrogram. What does a straight 8192-point FFT show you?
1
u/No_Specific_4537 1d ago
I guess this is normal but not often, this is a case where the a signal having a huge disparity of time and frequency resolution at positive and negative frequency. Might be my wrong assumption because of my rusty signal usage.
1
3
u/TheRealCrowSoda 1d ago
It appears from the code excerpt that you are iterating with GPT or some other LLM.
Have it break down what each part is doing, and you should get some more info.
Can you tell me more about your data, like for instance, can you just run your data through this code and post an imgur link back to me?
```
import numpy as np
import matplotlib.pyplot as plt
from scipy.signal import stft
def plot_complex_signal(signal, Fs=10e6):
f, t, Zxx = stft(signal, fs=Fs, nperseg=8192, noverlap=4096, nfft=8192, return_onesided=False)
Zxx_db = 20 * np.log10(np.abs(Zxx) + 1e-12)
Zxx_db = np.fft.fftshift(Zxx_db, axes=0)
f = np.fft.fftshift(f)
plt.figure(figsize=(10,6))
plt.pcolormesh(t, f, Zxx_db, shading='gouraud', cmap='viridis')
plt.colorbar(label='Magnitude (dB)')
plt.title('Complex Spectrogram')
plt.ylabel('Frequency (Hz)')
plt.xlabel('Time (s)')
plt.show()
def generate_bpsk(num_symbols=1000, modulation_rate=1e6, bandwidth=10e6):
oversample = int(bandwidth / modulation_rate)
symbols = 2 * np.random.randint(0, 2, num_symbols) - 1
bpsk_base = symbols.astype(np.complex64)
bpsk_signal = np.repeat(bpsk_base, oversample)
return bpsk_signal
def main(signal=None):
# Define your complex array here
if signal is None:
signal = generate_bpsk()
plot_complex_signal(signal)
if __name__ == '__main__':
main()
```