How to increase Spectrogram resolution?

The Spectrogram function also allows you to alter the window length, overlap and apply a windowing function to your data segment before FFT. You'll get better results if you utilize those (which requires some knowledge of DSP and your specific problem) instead of using the default parameters and the rectangle window.

For instance, the following shows the frequencies distinctly:

Spectrogram[data, 128, 64, BlackmanWindow, SampleRate -> 1023, 
    FrameLabel -> {"Frequency(Hz)", "Time"}] 


Urghhh ... I hate those "RustTones"... Nevertheless ^o^

sa = SpectrogramArray[data2];
ListDensityPlot[Transpose@Abs@sa, ColorFunction -> "DeepSeaColors", 
                AspectRatio -> 1/2, Frame -> None]

Spectrogram

ListDensityPlot[Transpose@Abs@sa, ColorFunction -> Hue, 
                AspectRatio -> 1/2, Frame -> None]

Spectrogram


Actually, we can get linear scale rather than log scale using wavelet transform, using the "LinearScalogramFunction" property of a ContinuousWaveletData object.

This is the default wavelet scalogram:

sampleRate = 1023;
data = Table[
   Piecewise[{{Sin[2 π 10 t], 0 <= t < 1/4}, {Sin[2 π 25 t], 
      1/4 <= t < 1/2}, {Sin[2 π 50 t], 
      1/2 <= t < 3/4}, {Sin[2 π 100 t], 3/4 <= t <= 1}}], {t, 0, 
    1, 1/sampleRate}];
cwd = ContinuousWaveletTransform[data, 
   DGaussianWavelet[5], {Automatic, 12}, SampleRate -> sampleRate];
WaveletScalogram[cwd, ColorFunction -> "RustTones"]

enter image description here

This uses the "LinearScalogramFunction" property to get a linear function and then plot the linear scale function using DensityPlot

f = cwd["LinearScalogramFunction"];
scaleToFrequency[
   s_] = (cwd["SampleRate"]/(s*cwd["Wavelet"]["FourierFactor"]));
DensityPlot[Abs[f[x, scaleToFrequency[y]]], {x, 0, 1}, {y, 2, 100}, 
 PlotPoints -> {300, 100}, ColorFunction -> "RustTones", 
 ClippingStyle -> Automatic, 
 FrameLabel -> {"Time (second)", "Frequency (Hz)"}]

enter image description here