spectrogram - auto settings for zlim are too wide

6 views (last 30 days)
Using the spectrogram function, the zlim settings that are created automatically seem to be too wide for my data. The resulting spectrogram uses less than half the colormap.
Here's a snippet of my code:
nfft=512;
noverlap=round(nfft*0.75);
window=hanning(nfft);
spectrogram( data, window, noverlap, nfft, sampleRate, 'yaxis' );
set( gca, 'YScale', 'log', 'box', 'on' );
ylim( [1.0 100.0] );
colormap parula;
colorbar off;
xlim( [10/60 70/60] );
And here's the spectrogram:
This is meant to be a plot that is created automatically many times, so I don't want to have to set zlim manually.
Any suggestions for getting a more impressive spectrogram?

Answers (2)

Adam Danz
Adam Danz on 29 Nov 2021
It's likely that the spectrogram is using the full range of the colormap but you're only seeing a portion of the colormap range because a very small section such as a single pixel or sub-pixel represents the far end of the colormap values.
To verify this, look at the colormap limits (CLim) and the CData limits. They probably match which means you're using the full range of the colormap.
specHandle = findobj(gcf, 'type', 'surface'); % assumes only 1 surface in figure
minCD = min(specHandle.CData(:))
maxCD = max(specHandle.CData(:))
get(gca, 'CLim')
You can rescale the colormap using caxis() which changes the CLim axis property.

Dave B
Dave B on 29 Nov 2021
I'd guess that the color limits (i.e. CLim not ZLim) are tightly fitting the data, but you have a pixel or two that is making it not what you want.
You might consider a little algorithm for choosing color limits using the color data
First, you'll need to find the values in the spectrogram image. If you're going to use the spectrogram to do the plotting:
nfft=512;
noverlap=round(nfft*0.75);
window=hanning(nfft);
sampleRate=5;
data=sin(linspace(0,2000*pi,10000))+rand(1,10000);
spectrogram( data, window, noverlap, nfft, sampleRate, 'yaxis' );
im = get(gca,'Children'); % Probably fine, as long as you haven't done hold on, plot
%im = findobj(gca,'type','Image'); % Slightly more robust
Perhaps you want to set the color limits to include 95% of the data? You could pick color limits based on the percentile of the data:
caxis([prctile(im.CData,2.5,'all'), prctile(im.CData,97.5,'all')])

Products


Release

R2020b

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!