Plotting spectrograms for multiple files
Show older comments
I have multiple acoustic files for which I would like to plot a spectrogram on a single plot.
I know how to plot one spectrogram:
[xbit,fs]=audioread(fullfname, [nlo nup]); %read in wav
xbit=detrend(xbit); %remove DC offset
calxbit=xbit*cal; %apply calibration
%Perform FFT and plot:
[S,F,T,P] = spectrogram(calxbit,window,overlap,nfft,fs,'yaxis');
figure(2);
h = pcolor(T,F,10*log10(P));
set(h,'EdgeColor','none');
This provides one figure with time on the x axis and frequency on the y-axis, and colourplot for intensity.
However, I would like to plot multiple spectrograms and so the x-axis represents multiple files which were collected over time e.g. every 5 minutes.
I considered that I could read in the acoustic data for multiple files and concatenate it, but this would not preserve any gaps in time between the subsequent files (which may or may not be negligible). I'd like to have the x tick marks represent the start time of each separate file perhaps.
Answers (1)
Bjorn Gustavsson
on 6 Oct 2021
Wouldn't you achieve the desired output by putting the different spectrograms in consecutive subplots?
Something like this perhaps:
nFiles = numel(fullfnames);
for iFile = 1:nFiles
fullfname = fullfnames{iFile};
t0 = Tstart(iFile);
[xbit,fs]=audioread(fullfname, [nlo nup]); %read in wav
xbit=detrend(xbit); %remove DC offset
calxbit=xbit*cal; %apply calibration
%Perform FFT and plot:
[S,F,T,P] = spectrogram(calxbit,window,overlap,nfft,fs,'yaxis');
sph(iFile) = subplot(1,nFiles,iFile);
h = pcolor(T,F,10*log10(P)); % Here you might want to add the start-time, t0, to T
% with proper conversion of time-format...
set(h,'EdgeColor','none');
end
Then you can adjust the spacing of the sub-plot-panels using sph (also consider using tile-nexttile)
HTH
8 Comments
Louise Wilson
on 6 Oct 2021
Bjorn Gustavsson
on 6 Oct 2021
Then you have something like 2 choises, as far as I can think up right now.
1, just add spectrograms as you process them with gaps between them with linear time from first to last.
2, add the spectrograms with a small gap between consecutive time-periods to mark gaps, and then put the
Xticks at the beginning of each spectrogram and set the XtickLabel to match the proper start-time. Perhaps something in line with this:
nFiles = numel(fullfnames);
t0 = 0;
dt = 1; % Just a random gap to put between spectrograms
for iFile = 1:nFiles
fullfname = fullfnames{iFile};
tStartstrings{iFile} = % you'll have to set/get/extract start-time for each spectrogram
[xbit,fs]=audioread(fullfname, [nlo nup]); %read in wav
xbit=detrend(xbit); %remove DC offset
calxbit=xbit*cal; %apply calibration
%Perform FFT and plot:
[S,F,T,P] = spectrogram(calxbit,window,overlap,nfft,fs,'yaxis');
h = pcolor(T,F,10*log10(P)); % Here you might want to add the start-time, t0, to T
% with proper conversion of time-format...
set(h,'EdgeColor','none');
t0(iFile+1) = t0 + T(end)+dt;
end
set(gca,'Xtick',t0,'XtickLabel',tStartstrings)
But now this feels more like a design-discussion and you have requirements and preferences I dont know about...
HTH
Louise Wilson
on 6 Oct 2021
Edited: Louise Wilson
on 6 Oct 2021
Louise Wilson
on 6 Oct 2021
Edited: Louise Wilson
on 6 Oct 2021
Bjorn Gustavsson
on 7 Oct 2021
Ah, my bad. Just plug a:
hold on
in after the pcolor-line, that should sort this out.
Louise Wilson
on 7 Oct 2021
Edited: Louise Wilson
on 7 Oct 2021
Louise Wilson
on 7 Oct 2021
Bjorn Gustavsson
on 8 Oct 2021
That might be because you now add the ID-time of each file to the start-time, which meand that if you have large gaps (you mentioned something like 5 minutes appart, and then each of those files were for a couple of seconds worth of data) between the spectrograms. The idea I proposed was to plot the first spectrogram at times between
0 and "10 s" the next spectrogram between "10 s"+dt and "20 s"+dt, the third spectrogram between "20 s"+2*dt and "30 s"+2*dt and so on. The next step is then to se the tick-marks to:
xTickTimes = 0:("10 s"+dt):(N*("10 s"+dt));
set(gca,'Xtick',xTickTimes)
Which should give you tickmarks at the start of each spectra, next you'll have to set the Xticklabel. For that you should have made a cell-array of the fname_st-contents, lets say you call that variable t_filestarts_all, then this should be:
set(gca,'XtickLabel',t_filestarts_all)
This way you will have an uneven time-axis, one scale for the file-start-times and between those the time-scales of the spectrograms.
HTH
Categories
Find more on Measurements and Spatial Audio in Help Center and File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!