For loop in matlab plot - matlab

Hello i am having some problems understading basic plotting in matlab.
I can understand why you would use a for loop when plotting data?
Can anybody explain this to me?
I am making a simple linear plot. Is there any reason this should be inside a loop

If you are making a simple plot there is virtually no reason to use a loop.
If you check doc plot you will find that plot can take some vectors as input, or even matrices for more interesting situations.
Example:
x=0:0.01:1;
y=sin(x);
plot(x,y)

No there is no need in Matlab to use a for loop for plotting. If you are looking for a simple linear plot your code could look like this:
x=1:100;
y=3*x+4;
plot(x,y)
As you see there is no for loop needed. Same goes for nearly all plots and visualization.

A possible reason to use a for loop to plot thing may be having several data to plot in a single matrix. Say you have two matrix Ax (MxN) and Ay (MxN) where N the length of each data and M is the amount of different data wanted to plot. For example like in this case N is 201 and M is 3:
% Create Ax and Ay
Ax=meshgrid(0:0.1:20,1:3);
Ay=zeros(size(Ax));
% Sinusoidals with different frequencies
for k=1:3
Ay(k,:)=sin(k.*Ax(k,:));
end
% create colours
colorVec = hsv(3);
% Plot
hold on
for k=1:3
plot(Ax(k,:),Ay(k,:),'Color',colorVec(k,:))
end
hold off
You get:

Related

How do I plot inside a for loop? Matlab

I'm trying to plot a straight line from a point in x to different values of t, thereby making a line in a for loop. But I see no lines generated in my figure in MATLAB
Following is my code:
t=linspace(0,8,11)
xs=(1.+t).^0.5
x0=xs./(1.+t)
m=size(t)
n=max(m)
hold on
for k=1:n
plot(x0(k),t(1:k),'-')
hold on
end
Thanks
You do not need the loop to perform the plot.
plot(x0,t,'-')
Will work just fine! Unless you were attempting to plot points...use scatter() for that:
scatter(x0,t)
plot() and scatter() (and most of Matlab's functions) are meant to be used with vectors, which can take some time to get used to if you are used to traditional programming languages. Just as you didn't need a loop to create the vector x0, you don't need a loop to use plot().
You are adding one point in Y axis along a line in X Axis use this code
t=linspace(0,8,11)
xs=(1.+t).^0.5
x0=xs./(1.+t)
m=size(t)
n=max(m)
hold on
for k=1:n
plot(x0(1:k),t(1:k),'-')
hold on
end
for more fun and see exactly how for is performed use this for loop
for k=1:n
pause('on')
plot(x0(1:k),t(1:k),'-')
hold on
pause(2)
end

Placing gaussian function at different points on mesh

I am looking to create a random distribution of gaussian curve shapes on a large mesh. I basically want to take this function :
Z = 0.3*exp(-5*(x.^2+y.^2))-0.1;
Z(Z<0)=0;
and be able to choose its location (in x & y coords), and have multiple plots.
So at the moment, I have this:
But I would like to have this generated:
Is there a reasonably simple way to do this? I have tried to play around with the code but I am afraid I'm not a mathematics, nor a MATLAB expert.
Any help would be much appreciated.
Look at this!
the way this works:
Generate random point
Check if point is closer than sigma
If its not, then create a gaussian there!
repeat until Ngaussians reached
code:
clear
n_gaussians=15;
gaussians=0;
sigma=1; % std
mindist=sigma; % if distance is smaller than this gaussians "collide"
[x,y]= meshgrid(-5:0.1:5,-5:0.1:5);
used=[];
Z=zeros(size(x));
while gaussians<n_gaussians
xm=(rand(1)-0.5)*10;
ym=(rand(1)-0.5)*10;
notvalid=0;
for ii=1:size(used,2)
% if we are too close to any point.
if norm([xm-used(1,ii),ym-used(2,ii)])<mindist
notvalid=1; % do not add this gauusian
end
end
if notvalid
continue
end
used(:,end+1)=[xm;ym];
Zaux = 0.3/sigma*exp(-5*((x-xm).^2+(y-ym).^2)/sigma.^2)-0.1;
Zaux(Zaux<0)=0;
Z=Z+Zaux;
gaussians=gaussians+1;
end
surf(x,y,Z);
axis equal

i have 100*100 matrix, how can i make plot3 graph?

I have a 100 x 100 matrix and i have to use plot3 in MATLAB environment to graph this data. I tried plot3(matrix name) but I faced this error "not enough input arguments". I think plot3 needs 3 input arguments, but I only have this matrix of data. could anyone help me to solve this problem? Is there any alternative for plot3 when we don't have enough arguments?
I need a graph like this:
I think you want to plot the values in a figure as a sort of surface element. What you can do then is:
[X,Y] = size(matrix);
figure;
surface(1:X,1:Y,matrix);
What this does is that it creates a vector for both X and Y indices, as possible in surface. The X and Y indices are obtained by setting them as integers from 1:size, so basically you assign the location of each matrix element to an index.
Note that you can strictly speaking use surface(matrix) as well, but the former approach allows you to use custom indexing, as long as the lengths of the vectors X and Y are the same as the size of your matrix.
For the waterfall use:
figure;
waterfall(matrix);
Sample code:
A=rand(100);
figure;
waterfall(1:100,1:100,A);
Gives:
where you can play around with the name-value pairs, see the documentation on that.
I think what you need is mesh or surf instead of plot3.
plot3 draws a line in 3d-space, so it will need three vectors of the same length (one for each dimension).
When you have a matrix, one reasonable way of displaying it is as a surface in 3d space, which is done by the functions mesh and surf.
Try it out! I hope i helps!

Matlab, figures and for loops

I am trying to plot the following simple function; $y=A.*x$ with different A parameter values i.e. A=0,1,2,3 all on the same figure. I know how to plot simple functions i.e. $y=x$ by setting up x as a linspace vector so defining x=linspace(0,10,100); and I know that one can use the hold command.
I thought that one could simply use a for loop, but the problem then is getting a plot of all the permutations on one figure, i.e. I want a plot of y=t,2*t,3*t,4*t on the same figure. My attempt is as follows:
x=linspace(0,10,100);
%Simple example
Y=x;
figure;
plot(Y);
%Extension
B=3;
F=B*x;
figure;
plot(F);
%Attempt a for loop
for A= [0,1,2,3]
G=A*x;
end
figure;
plot(G);
This is how I would plot your for loop example:
figure;
hold all;
for A=[0,1,2,3]
G=A*x;
plot(G);
end
figure creates a new figure. hold all means that subsequent plots will appear on the same figure (hold all will use different colours for each plot as opposed to hold on). Then we plot each iteration of G within the loop.
You can also do it without the loop. As with most things in Matlab, removing the loop should give improved performance.
figure;
A=[0,1,2,3];
G=x'*A;
plot(G);
G is the outer product of the two vectors x and A (with x having been transposed into a column vector). plot is used to plot the columns of the 100x4 matrix G.

STFT computation without using spectrogram function!

I was trying to plot STFT using plot3 in MATLAB but failed. Can somebody guide me how to do that? My MWE is given below:
%% STFT Computataion
clear; clc; clf;
%% Get input and calculate frame size and overlap/shift
[Y,Fs]=wavread('D_NEHU_F0001_MN_10001');
frame_size=round(20*Fs/1000); % calculate frame size for 20ms
frame_shift=round(10*Fs/1000); % calculate frame shift for 10ms
%% Plot the input signal in time domain
t=1/Fs:1/Fs:(length(Y)/Fs);
subplot(2,1,1)
plot(t,Y);
title('Speech signal in time domain');
ylabel('Magnitude of samples');
xlabel('time in seconds');
%% Calculation of STFT
%NoOfFrames=floor((length(Y)/frame_shift)-1);
NoOfFrames=length(Y)-frame_size;
j=1;
%for i=1:frame_shift:(length(Y)-frame_size)
for i=1:frame_shift:((length(Y)-frame_size))%+frame_shift)
sp_frame=Y(i:(i+frame_size)).*hamming(frame_size+1);
sp_frame_dft=abs(fft(sp_frame)); % Compute STFT
sp_frame_array(:,j)=sp_frame_dft;
j=j+1;
end
%% Plot the STFT in 3D
[rows,cols]=size(sp_frame_array);
F=linspace(1/Fs,Fs/2000,cols);
T=1/Fs:(frame_shift*Fs/1000):(cols*(frame_shift*Fs/1000));
Z=1:frame_size+1;
subplot(2,1,2)
%mesh(sp_frame_array);
%surf(sp_frame_array,'EdgeColor','none');
plot3(T,F,sp_frame_array);
I am not sure what your question exactly is about, but I guess the problem is, with the provided code, that you do not get a plot similar to the one you'd get, say, with surf.
Furthermore, I am also not quite sure why you would want to use plot3, maybe to get the labels on the time and frequency right ? you could do that all the same with surf:
surf(T, F, sp_frame_array,'EdgeColor','none');
As a matter of fact, the reason why your plot3 does not give the same figure is because the arguments of plot3 must be three matrices of the same size (check it on help plot3). Your code should actually be broken on Matlab, which it's not, according to my test. Well, once again Matlab allowing people to mess around without warnings (go Python! :D)... Anyway, try to set the matrices more like the following:
F=linspace(1/Fs,Fs/2000, rows); % note: has to be rows, not cols here!
Fmat = F(:) * ones(1,cols); % or use repmat
T=1/Fs:(frame_shift*Fs/1000):(cols*(frame_shift*Fs/1000));
Tmat = ones(rows,1) * T(:)';
plot3(Tmat,Fmat,sp_frame_array);
While this will normally produce something more in line with what I would expect in drawing a spectrogram, I'd still make some remarks:
your F vector should go up to Fs, because of the way you filled sp_frame_dft in. More specifically, it should go from 0Hz to Fs - Fs/rows:
F = linspace(0,Fs*(1-1/rows)/1000,rows); % in kHz
you would probably like to draw the amplitudes in dBs:
plot3(Tmat,Fmat,db(sp_frame_array));
plot3 draws one line per column of the provided matrices. That means potentially lots of lines to draw! As #atul-ingle asked, are you sure this is what you want? Maybe waterfall would provide a better rendering at a lower cost?
waterfall(T,F,db(sp_frame_array));
Well, you'll get the lines for the rows, instead of the columns, so you might need to transpose if the latter is what you want.
You might also prefer to visualise only the first half of the matrix (because the frequencies higher than Fs/2 are only mirrors of the other half of the matrix).
Hope that helps!