Time series analysis: Obtaining the spectrogram using the Gabor transform

The practice of time series analysis deals with fluctuations which vary in time.

The ubiquitous by now Fourier Transform, has provided us with a convenient tool to model such functions.

Several variations of the Fourier Transform algorithm are available as open source code, and have been optimized many times over the years. The most widely used of all, being the Fast Fourier Transform (FFT).

However, the main drawback to the FFT is the fact that it deals with periodic stationary signals that repeat til infinity.

Fourier Transform

For truly periodic signals such as the one shown below, the FFT works like magic, and the true signal from noise is instantaneously distinguishable.


In practice, rarely do we find trends which are truly stationary in time.

While it may be widely understood and relatively easy to implement, usage of the FFT is inherently flawed.

While we do know the amplitude of these fluctuations, we do not know when exactly, do they occur.

With this understanding, we come to the conclusion that it is not the best method of time series analysis.

In this post, we shall explore a different method that may potentially address the shortcomings of the FFT.

The Gabor transform

The Gabor transform (GT) is a fairly recent addition to the toolbox of mathematical methods and it builds upon the math of the FFT.

The Fourier Transform was introduced in 1822, by French scientist Jean-Baptiste Joseph Fourier.

Wikipedia: Joseph Fourier

While the GT was pioneered in the year 1971, by Hungarian Nobel Laureate in Physics, Dennis Gabor.

Wikipedia: Dennis Gabor

The GT improves upon the FFT, by adding a “time localisation window function”.

Recall the Fourier Transform:

Fourier Transform

Addition of the window function is given by the familiar gaussian distribution:

Gaussian distribution function

And the Gabor transform is comprised of both:

Gabor transform

A code sample for audio analysis via the GT is demonstrated in the following book.


I have attempted to execute and understand the code simples within, and try to re-apply it to stock market data, as I did in a previous article on the FFT algorithm, where I did an analysis on Tesla stock price movements.

A similar series of steps will be shown here.

import numpy as np
import matplotlib.pyplot as plt
plt.rcParams['figure.figsize'] = [12, 8]
plt.rcParams.update({'font.size': 18})
dt = 0.001 #Sampling interval of 0.001 seconds.
t = np.arange(0,2,dt) #Time duration of 0 to 2.00 seconds
f0 = 50 #Initial frequency of 50 hz
f1 = 250 #Final frequency of 250 Hz
t1 = 2 #Period of time evolving signal = 2 secs

To quote from the book:

“we construct an oscillating cosine function where the frequency of oscillation increases as a quadratic function of time…”

#Audio signal in Python representationx = np.cos(2*np.pi*t*(f0 + (f1-f0)*np.power(t,2)/(3*t1**2)))#Sampling frequency of 1 kilohertz, given by (1/period)fs = 1/dt             ##Plotting the Spectrogram function of the audio signal plt.specgram(x, NFFT=128, Fs=1/dt, noverlap=120, cmap='jet_r')
plt.xlabel("Time (seconds)")
plt.ylabel("Frequency (Hz)")

As expected, we see the visual representation of the frequency that evolves quadratically in time.

With the spectrogram, we now have 3 facets of information about the signal.

  1. The frequency
  2. The time that said frequency occurs.
  3. The dominant frequency at each moment in the time (given by color bar)

Point number 3 is the crucial aspect here.

Dominant frequency at each moment in time.

We have potentially found a solution that addresses the shortcoming of the FFT.

We now attempt to test it on the real world example of stock price movements, namely, Tesla.

import yfinance as yf            #The Yahoo Finance library tsla_df = yf.download('TSLA',

Confining our analysis to the “adjusted closing” price:

df = tsla_df[['Adj Close']]
< (125, 1) > # 125 days of the adjusted closing pricedf.head()

A quick eyeball of the trends that take place over the entire 125 day period, via a plot.

plt.ylabel('Price ($)')
plt.title('Tesla Price')

And now, we examine the raison d’être of the gabor transform:

The time localisation window function.

plt.specgram(df, NFFT=256, Fs=2, noverlap=10, cmap='jet_r', mode='psd')
plt.ylim([0, 0.2])

A spectrogram plot of the entire 125 period.

The observations demonstrate some rather intuitive conclusions.

  1. The dark blue bands occur at very low frequencies.

Which tells us that the more powerful fluctuations in this time series are fairly rare. This make sense as the overall trends of the stock where the large rises and falls occur over periods of 3 to 4 months.

2. The yellow and green bands occur at relatively higher frequencies.

The conclusion here is that fluctuations of higher frequencies are less powerful. The causes behind these fluctuations may occur more frequently, but they do not exert a great influence.

These 2 takeaways:

Allow one to conclude for now, without any additional information, that the volatility across this period can be said to be fairly low.

If we want to confine our analysis to different periods, we now have the power to accomplish what the original fourier transform cannot do.

We can shift the time localisation window.

plt.specgram(df, NFFT=128, Fs=2, noverlap=120, cmap='jet_r', mode='psd')plt.specgram(df, NFFT=256, Fs=4, noverlap=120, cmap='jet_r', mode='psd')

By tweaking parameters such as the period of analysis, and also the sampling interval, we can begin to see fluctuations of varying frequencies and intensity.

Lacking a meaningful understanding of the financial markets at this time, I do not have the wherewithal to draw meaningful conclusions.

But with the assistance of someone who has the requisite knowledge, we could definitely unearth some.

And that is where the power of the gabor transform becomes apparent.

And that is all for now!

Physics major from sunny Singapore! https://www.linkedin.com/in/daryl-tng-773694137/