How can I improve the resolution of a spectrogram of a low-frequency signal with high sampling frequency (Python)? Imagine you have signals $x_1(t)$ and $x_2(t)$ that contain a limited number of periods of low frequency oscillations and are sampled at 44100Hz (coming from an external source) and you want to obtain their spectrograms.

I chose nperseg=8820 to capture one period of 5Hz (44100/5=8820) in an analysis window and noverlap=1 to move in steps of one sample.


As shown in the figure below, after zooming the frequency axis, the frequency resolution in this low-frequency region is poor. Are there ways to improve this resolution? By setting special parameters of the spectrogram function or by downsampling for instance?
And why does the spectrogram of $x_2(t)$ change color over time?


import numpy

import scipy.signal
import matplotlib.pyplot as pplot

fs = 44100
t = numpy.linspace(0, 100000, 100001) / fs
x1 = numpy.sin(2*numpy.pi*5*t)
x2 = numpy.sin(2*numpy.pi*5*t**2)

f1, t1, Sxx1 = scipy.signal.spectrogram(x1, fs, nperseg=8820, noverlap=1)
f2, t2, Sxx2 = scipy.signal.spectrogram(x2, fs, nperseg=8820, noverlap=1)

pplot.figure(1)
pplot.clf()
pplot.subplot(2,2,1)
pplot.plot(t, x1)
pplot.subplot(2,2,2)
pplot.plot(t, x2)
pplot.subplot(2,2,3)
pplot.pcolormesh(t1, f1, Sxx1)
pplot.ylim([0, 30])
pplot.subplot(2,2,4)
pplot.pcolormesh(t2, f2, Sxx2)
pplot.ylim([0, 30])
pplot.show()
I'm not sure but there's something called the time-frequency resolution limit, basically the shorter your windowing interval the broader your spectrum is going to be.

The frequency resolution in the low frequency area may be poor because of this. Things like wavlets attempt to resolve this problem but i dont know anything about them.