# jumps in spectrogram of frequency ramping

I create spectrogram of a sine wave that changes its frequency from 60 MHz to 70 MHz over a period of 1 millisecond.

can someone help me understand why I see those jumps? how can I make it smoother?

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

def wave_create(duration: float,
samplerate: int,
frequency: int,
f_final=0,
bittage=14
) -> list:

"""this function can create wave signal in given frequency
Args:
duration (float): length in seconds
samplerate (int): sampling rate
frequency (int): initial frequency
f_final (int, optional): ramping of initial frequency to final.

Returns:
list: the wave signal
"""

amplitude = 2 ** (bittage - 1)
num_samples = int(duration * float(samplerate))
k = np.linspace(1, num_samples, num_samples)
if f_final:
frequency = np.linspace(frequency, f_final, num_samples)

signal = amplitude*np.sin(2*np.pi*frequency*k/samplerate)

return signal

sample_rate = 2**30
duration_desired = 1e-4
f_first = 60e6
f_final = 75e6
signal_final = wave_create( duration_desired, 1e9, 60e6, 75e6)
frequencies_spectugram, times, Sxx = signal.spectrogram(signal_final, fs=sample_rate, nperseg=512, noverlap=511)

#Plot the spectrogram with a black and blue colormap
plt.figure(figsize=(10, 5))
plt.imshow(Sxx, cmap='Blues', aspect='auto', origin='lower', extent=[times.min(), times.max(), frequencies_spectugram.min(), frequencies_spectugram.max()])
plt.colorbar(label='Amplitude')
plt.ylabel('Frequency (Hz)')
plt.ylim([40e6,90e6])
plt.xlabel('Time (s)')
plt.title('Spectrogram of Changing Frequency Sine Wave')
plt.show()


• Your spectrogram result does not match what you’re describing your signal to be.
– Jdip
Commented Nov 1, 2023 at 14:24

As you can (or should) clearly see, your signal is not correctly generated.

• You want a linear sweep with duration $$T = 1\,\texttt{ms}$$ but you're defining the duration to be 1e-4 which is $$0.1\,\texttt{ms}$$
• Next you define a sampling rate sampling_rate = 2**30 that you use to construct the spectrogram, but you generate your signal with a sampling rate of 1e9
• Your window is too short, so your frequency resolution is too low.
• More importantly, you're not correctly generating a linear sweep.

With these things in mind, here is a corrected version of your code.

def wave_create(duration: float,
samplerate: int,
frequency: int,
f_final=0,
bittage=14
) -> list:

"""this function can create wave signal in given frequency
Args:
duration (float): length in seconds
samplerate (int): sampling rate
frequency (int): initial frequency
f_final (int, optional): ramping of initial frequency to final.

Returns:
list: the wave signal
"""

amplitude = 2 ** (bittage - 1)
num_samples = int(duration * float(samplerate))
if f_final:
frequencies = np.linspace(frequency, f_final, num_samples)

# correct linear sweep
signal = amplitude*np.sin(2*np.pi*np.cumsum(frequencies)/samplerate)

return signal

sample_rate = 2**30
duration_desired = 1e-4 # do 1e-5, 1e-4 takes a lot longer computationally.
f_first = 60e6
f_final = 75e6
signal_final = wave_create( duration_desired, sample_rate, 60e6, 75e6)
win_len = 4096 # for better frequency resolution
win = signal.windows.hamming(win_len) # use hamming window to prevent spectral leakage
frequencies_spectugram, times, Sxx = signal.spectrogram(signal_final, fs=sample_rate, nperseg=win_len, noverlap=win_len-1, window=win)


• 1. time duration and sample_rate are just constant have no effects on the jumps. 2. The sumcum you use changing the calculation of the signal which is maybe a good idea but... The other things you used are making the output smoother but not represnting the real signal . which is not what I wanted to do, but thanks, it helps me think. 3. the hamming window changing the fft calculation without changing the signal. 4. the window len esspecially changing the fft calculation without changing the signal so it is not helping me contruct a better signal. Commented Nov 2, 2023 at 9:03
• I need a way to change the real signal not just the representation of the spectugram. From everything you suggested the only thing you really changed in the signal is the cumsum instead of k*frequency.... which is maybe a nice smoothing technique but not really solving the problem Commented Nov 2, 2023 at 9:29
• You seem to assume you know things that I’m sorry to say you don’t. 1) fair enough, just pointing out that you gave us code that does not match your specifications. 2) using cumsum is not a “smoothing technique”, or a “good idea”. It’s the correct way to create a linear sweep. That does change the “real” signal, since the way you were constructing it was wrong. 3) using a hamming window has nothing to do with how the fft is computed. It prevents spectral leakage. 4) this gives you better resolution for your spectrogram.
– Jdip
Commented Nov 2, 2023 at 15:28
• Bottom line, the jumps you see are a result of how you’re defining the parameters of your analysis, and how you constructed your signal in the first place. I showed how to define the parameters better, but since you’re adamant on only changing the way your signal is constructed, well I did that too.
– Jdip
Commented Nov 2, 2023 at 15:32
• Can you find me a source of knowledge to this operation of sumcum? As I see it instead of calculating at time k , f(k)*k you do f1 + f2 + .... fk . which is kind of smoothing/avaraging for the frequency term... actually I'm new to signal processing but I look at the mathematics. secondly, when I also see in my example that there are frequencies above 70 Mega. Can you tell how they exist? Commented Nov 5, 2023 at 14:49