Create 2D Spectrogram in Matlab - matlab

I am in need of plotting a 2D spectrogram of a signal in Matlab. I need it for a printed assignment, hence the 3D image makes no sense. However, when the signal is plotted using Spectrogram it automatically produces a 3D plot of the signal.
My Code:
Dataset = 1; % Dataset to be analysed
N = 1024; % Window size
Beta = 12; % Kaiser window beta value (small = narrow main lope)
Overlap = 800; % Window overlap
Threshold = -150; % Minimum magnitude before threshold
spectrogram(Enclosure{Dataset}(1:end),kaiser(N,Beta),Overlap,2048,fs,'MinThreshold',Threshold,'yaxis');
which produces a graph that looks like this:
But it is seen from the top, and the graph is really showing this:
The reason why i need it to specifically be 2D (and why i don't settle with a screenshot) is because i am using Matlab2tikz to convert Matlab figures into Tikz figures in LaTex. with the 3D images i get figures of +100 Mb and 2D will reduce the size to <1Mb.

I don't know what version of Matlab you are using but in 2015a you should be able to get a handle to the figure with the 3D plot and change the view angle to 2D:
view(0,90);
I've also got an example of how you can make your own 2D plot from the outputs of spectrogram() using a similar method:
x = [0:0.01:100];
y = sin(5*x);
y = awgn(y,0.1);
[S,F,T,P] = spectrogram(y,200,0,length(y)*5,100);
[m,n] = size(P);
figure(2)
surf(F,T,zeros(n,m),P','EdgeColor','none')
view(0,90)
xlabel('Frequency')
ylabel('Time (s)')
The output looks like this:
Hopefully since there is no altitude information, the figure size might be smaller but I can't test that since I don't have Matlab2tikz.

One option is to capture whatever its plotted and then plot it as an image. You can do this using getframe
if you do
F=getframe(gca);
cla;
imshow(F.cdata);
You'll get exactly what you will be seeing before, but as an image.
However I think it defeats a bit the purpose of Matlab2Tikz, as the idea os that you have Tikz code describing your data...

You can try the following:
[~,F,T,ps]=spectrogram(Enclosure{Dataset}(1:end),kaiser(N,Beta),Overlap,2048,fs,'MinThreshold',Threshold,'yaxis').
% Output the spectrum in ps
imagesc(T,F,10*log10(ps))
% Generate a 2d image
view(270,90)
xlabel('Time [s]')
ylabel('Frequency [Hz]')
c=colorbar;
c.Label.String='Power [dB]';
% Extra setting to make the plot look like the spectrogram
Good luck

Related

Histogram fit and kernal Density plot in MATLAB

I want to plot histogram fit and kernel Density curve in one plot means in I figure ks density curve and histfit in one frame .
Can someone help me how to do that.
I am just presenting an example code what I want to do.
Thanks a lot .
x = rand([1 50])
figure(1)
histfit(x)
hold on
[f,xi] = ksdensity(x);
hold off
figure
plot(xi,f);
The function calls for plotting are incorrect. Essentially, hold on asks MATLAB to plot everything thereafter, overlapping the previous figure. hold off disables this and overwrites the previous figure. Hence, run the code like this:
x = rand([1 50])
figure(1)
histfit(x)
hold on
[f,xi] = ksdensity(x);
plot(xi,f);
hold off

matlab contour plot time depth density

I need assistance making a nice contour plot. I have data from an underwater glider that dives and climbs repeatedly from the surface of the ocean to around 30 m, in this case.
I think my issue is with interpolating the data, and I am not sure how to proceed. Here is the contour plot of density I have generated this far.
The Contour plot of density was generated using this code
xlin = linspace(min(time),max(time),500);
ylin = linspace(min(depth),max(depth),500);
[X,Y] = meshgrid(xlin,ylin);
Z = griddata(time,depth,density,X,Y);
[C,h] = contour(X,Y,Z,[1022.0, 1022.5, 1023.0, 1023.5, 1024.0, 1024.5, 1025.0, 1025.5, 1026.0],'color',[0.5 0.5 0.5]);
v = [1022.0, 1022.5, 1023.0, 1023.5, 1024.0, 1024.5, 1025.0, 1025.5, 1026.0];
clabel(C,h,v,'fontsize',8);
set(gca,'ydir','reverse');
I want the plot to have smooth contour lines. Once I get the contour plot to look good I will overlay it on salinity and temperature scatter plots.
Please let me know how I can make a better looking contour plot.
Is it an issue with interpolation? Or the way I gridded the data?
Thanks very much! Please be specific and give code examples if you've played with the data.
Here is the time, depth, and density matlab data: https://www.dropbox.com/s/agi70zh7haggf07/data.mat?dl=0
The problem is that bunch of your interpolated data are missing. I mean that Z has a bunch of NaNs:
xlin = linspace(min(time),max(time),500);
ylin = linspace(min(depth),max(depth),500);
[X,Y] = meshgrid(xlin,ylin);
Z = griddata(time,depth,density,X,Y);
%surf(X,Y,Z) %also interesting
spy(isnan(Z));
Result:
Your input data are somehow ill-defined, and griddata gives up. Here's why:
>> sum(isnan(density))
ans =
3174
Fix the NaNs in your raw data, and you'll most probably fix the plot.
Update
I threw away your NaNs:
inds=~isnan(density);
time=time(inds);
depth=depth(inds);
density=density(inds);
to see how the result looks like. It turns out that your original code is already looking OK to me!
Original on the left, de-NaNed version on the right:
So... maybe your datetime transformation is off? Or your time limits, not showed in your original code?

Using streamslice with color for velocities

I am using streamslice command to visualize my flow. I want to add color depending on magnitude of velocities but there seems to be no function argument in streamslice to do so. The function is given as:
% x - x-coordinates
% y - y-coordinates
% u,v - vector volume data
h = streamslice(x,y,u,v)
The function produces this image
If you want to use streamslice, I can suggest something. It would need some tweaking to get it look like a cool figure, but it does the job, I guess. the idea is to combine a surf plot with the streamsilces plot.
Look at the result. I guess that with better a colormap and with some tricks getting the data handle of the streamsliceto change the line colour it could work nicely, speciall yin Matlab R2014b or higher.
CODE:
clear;clc;
load wind
% Use only a piece of this datasheet
x=x(:,:,5);
y=y(:,:,5);
u=u(:,:,5);
v=v(:,:,5);
mag=sqrt(u.^2+v.^2);
figure
hold on
surf(x,y,mag-max(mag(:)),'FaceColor','interp','Edgecolor','none')
colormap('hot')
streamslice(x,y,u,v)
axis([min(x(:)) max(x(:)) min(y(:)) max(y(:)) -max(mag(:)) 0])

project a sphere to a plane using matlab

This is probably very basic matlab, so forgive me.
I use the command sphere to create a 3D sphere and have the x,y,z matrices that will produce it using surf. For example:
[x,y,z]=sphere(64);
I'd like to project (or sum) this 3D sphere into one of the Cartesian 2D planes (for example X-Y plane) to obtain a 2D matrix that will be the projection of that sphere. Using imshow or imagesc on the output should look something like this:
simple summing obviously doesn't work, how can I accomplish that in Matlab?
It is possible that I completely misunderstand your question, in which case I apologize; but I think one of the following three methods may in fact be what you need. Note that method 3 gives an image that looks a lot like the example you provided... but I got there with a very different route (not using the sphere command at all, but computing "voxels inside" and "voxels outside" by working directly with their distance from the center). I inverted the second image compared to the third on since it looked better that way - filling the sphere with zeros made it look almost like a black disk.
%% method 1: find the coordinates, and histogram them
[x y z]=sphere(200);
xv = linspace(-1,1,40);
[xh xc]=histc(x(:), xv);
[yh yc]=histc(y(:), xv);
% sum the occurrences of coordinates using sparse:
sm = sparse(xc, yc, ones(size(xc)));
sf = full(sm);
figure;
subplot(1,3,1);
imagesc(sf); axis image; axis off
caxis([0 sf(19,19)]) % add some clipping
title 'projection of point density'
%% method 2: fill a sphere and add its volume elements:
xv = linspace(-1,1,100);
[xx yy zz]=meshgrid(xv,xv,xv);
rr = sqrt(xx.^2 + yy.^2 + zz.^2);
vol = zeros(numel(xv)*[1 1 1]);
vol(rr<1)=1;
proj = sum(vol,3);
subplot(1,3,2)
imagesc(proj); axis image; axis off; colormap gray
title 'projection of volume'
%% method 3: visualize just a thin shell:
vol2 = ones(numel(xv)*[1 1 1]);
vol2(rr<1) = 0;
vol2(rr<0.95)=1;
projShell = sum(vol2,3);
subplot(1,3,3);
imagesc(projShell); axis image; axis off; colormap gray
title 'projection of a shell'
You can project on the X-Y plane in Matlab by using:
[x,y,z] = sphere(64);
surf(x,y,zeros(size(z)));
But I think you should not use Matlab for this, because the problem is so simple you can do this analytically...
I would look at map projections, which are designed for this purpose.
A search on "map projections matlab" yields documentation on a Matlab mapping toolbox. However, if you want or need to roll your own, there is a good summary at the USGS website, as well as a wikipedia article.

How to automatically spin a 3d hsitogram in matlab?

I have a 3d histogram in matlab. Is it possible to automatically spin it i.e to get the 3d effects. I want to show it as a video in PowerPoint where the 3d histogram swivels.
thanks
A somewhat cumbersome way to do this would be to rotate the chart manually using the view command. You can update azimuth and elevation views of any 3D plot using this command.
Creating a video of it requires capturing the plot window using a command sequence like this (note, you're going to get the gray background, so you might want to change the background color):
% create figure and get handle to it (store handle in hf)
hf = figure(1);
% [create 3d plot]
% Create file to hold the animation
aviobj = avifile('mymovie.avi', 'compression', 'Cinepak');
% loop with some criteria for rotation
while(...)
% update view using view command
view(az, el);
% get Matlab to flush the drawing buffer (effectively forces a plot update)
drawnow;
% capture frame and write to the avi file
aviobj = addframe(aviobj, hf);
end
% end loop
% Close movie (flushes write buffer and finishes the video)
aviobj = close(aviobj);
You can use the same tactic without the avifile stuff to rotate the plot using a script in Matlab, though you might want to use a pause command to slow down the frame change.
Let us make sure we are talking about the same thing here. A 2-D histogram would have bins of a specified X and Y range and the count would be shown on a Z axis. A 3-D histogram would have bins in the X and Y and Z ranges with the count shown in some other way (color?) You would need slicing for a 3-D histogram to make sense.I am going to assume that you mean a 2-D histogram that looks like a bunch of blocks coming out of the ground.
I think you will be better served to make this 2-D histogram into an image, where each pixel represents a specific bin in X and Y and the color specifies the count in that bin. I think the motion will only confuse the data. Use image or imagesc or imshow for this. Also, I would recommend an intensity based colormap (>>colormap), like spring or winter. This make the differences more apparent. Turn on the colorbar (>>colorbar)