Making parametric plot with matlab - matlab

Is it possible to plot and make my x and y axis be depended on a parameter?
For example, I'd like that my x axis will be divided to 0 1/10L 2/10L 3/10L....L
and to plot the function on that exact axis, is it possible?
This is what I tried:
x = 0:0.1*L:10*L
plot(x,func1(x))
hold on
plot(x+xShift,func2(x)+yShift)
grid on
the shifts I'm adding are just some shifts because I'd like the second function to start from a different x and y.

This should do the trick:
L = 4;
xShift = 5;
yShift = 2;
y = #(x) x .^ 2;
x = 0:(0.1*L):(10*L);
x_shifted = x + xShift;
y = y(x);
y_shifted = y + yShift;
plot(x,y)
hold on;
plot(x_shifted,y_shifted)
hold off;
grid on;
ticks = 0:(10*L) + xShift;
set(gca,'XTick',ticks);
lim = max(y_shifted);
set(gca,'YLim',[0 max(y_shifted)]);
Output:

Related

Plot two-dimensional array as elliptical orbit

I am attempting to plot an elliptical orbit based on a 2-D position array, beginning at p= [5 0]. The plot charts positions from a timeframe t, here between 0 and 100. The calculation uses the formula F = -(p/||p||)(m*M/(p^2) to approximate acceleration and velocity. The result should look like the following:
This is my current code. It plots a completely different shape. Is the problem in my way of interpreting the force equation?
Any other help and comments are much appreciated.
t = 0; p = [50 0]; v = [0 8]; %Initial conditions
dt = 0.05;
M = 10000; m= 1;
tmax = 100;
figure, hold on
d = 0.001
clf;
while t < tmax
F = -(p./norm(p)).*(m*M./(p*p'));
a = F./m - d*v;
v = v + a*dt;
p = p + v*dt;
t = t + dt;
plot(p(1),t,'o','MarkerSize',0.5);
hold on;
plot(p(2),t,'o','MarkerSize',0.5);
end
You want p(1) in the x axis and p(2) in the y axis, with t as a parameter. So you need to replace the two plot lines by plot(p(1),p(2),'o','MarkerSize',0.5); (keeping hold on):
t = 0; p = [50 0]; v = [0 8]; %Initial conditions
dt = 0.05;
M = 10000; m= 1;
tmax = 100;
figure, hold on
d = 0.001
clf;
while t < tmax
F = -(p./norm(p)).*(m*M./(p*p'));
a = F./m - d*v;
v = v + a*dt;
p = p + v*dt;
t = t + dt;
hold on
plot(p(1),p(2),'o','MarkerSize',0.5); %%% modified line
end

how to draw random points inside an ellipse matlab

I want to fill this ellipse with N random points inside it
any help I'd be glad
clear ,close all;
xCenter = 15;
yCenter = 10;
xRadius = 3.5;
yRadius = 8;
theta = 0 : 0.01 : 2*pi;
N = 100; % N rand points
x = xRadius * cos(theta) + xCenter;
y = yRadius * sin(theta) + yCenter;
plot(x, y, 'LineWidth', 1);
axis square;
grid on;
I tried this code to generate 100 points inside the ellipse with specific parameters but I did not achieve my goal,
xCenter = 5;
yCenter = 3;
xRadius = 3.5;
yRadius = 8;
theta = 0 : 0.01 : 2*pi;
N = 100;
x = xRadius * cos(theta) + xCenter;
y = yRadius * sin(theta) + yCenter;
xq=(rand(N,1)*(2*yRadius) - yRadius);
yq=(rand(N,1)*(2*yRadius) - yRadius);
in = inpolygon(xq,yq,x,y);
hold on
inX = xq(in);
inY = yq(in);
outX = xq(~in);
outY = yq(~in);
plot(inX, inY , 'ro');
plot(outX, outY, 'b*');
plot(x, y, 'LineWidth', 1);
axis square;
grid on;
Sardar's answer produces points not evenly distributed within the ellipse. This code produces an even distribution of points:
xCenter = 15;
yCenter = 10;
xRadius = 3.5;
yRadius = 8;
N = 100;
% Generate points in the ellipse
t = 2*pi * rand(N,1);
d = sqrt(rand(N,1));
x = xCenter + xRadius * d .* cos(t);
y = yCenter + yRadius * d .* sin(t);
plot(x,y,'o')
The difference is the sqrt on the normalized (0 to 1) distance from the origin d. By computing this square root, you increase the density of points closer to the edge of the ellipse. This compensates for points otherwise being too dense close to the center. The uniform distribution of points along that normalized distance is what causes higher density of points near the center.
Generate random numbers for x and y axes between the specified limits, i.e. xRadius and yRadius, for the respective axes. Read Random Numbers Within a Specific Range to understand how to generate those random numbers.
hold on;
RndAngles = rand(N,1); %Same angle should be used
Xpoints = (xRadius.*rand(N,1) .*cos(2*pi*RndAngles))+ xCenter;
Ypoints = (yRadius.*rand(N,1) .*sin(2*pi*RndAngles))+ yCenter;
plot(Xpoints,Ypoints,'o'); %Plot those points
Output:

Streamline plot of cylinder

I have made this plot of streamlines around a cylinder with a radius of 1. Is there a way to remove whats inside the cylinder and maybe even high lite the cylinder with a different colour?
clear
% make axes
xymax = 2;
x = linspace(-xymax,xymax,100);
y = linspace(-xymax,xymax,100);
% note that x and y don't include 0
[X,Y] = meshgrid(x,y);
R = sqrt(X.^2 + Y.^2);
sin_th = Y./R;
cos_th = X./R;
U = 1;
a = 1;
psi = U*(R - a*a./R).*sin_th;
figure
contour(X,Y,psi,[-3:.25:3],'-b');
You can mask what you don't want to draw with nan:
psi((Y>0 & psi<0) | (Y<0 & psi>0)) = nan;
and than draw a circle on it:
rectangle('Position', [-1 -1 2 2],'Curvature',[1 1],'EdgeColor','r')
Here is the code and result:
% make axes
xymax = 2;
x = linspace(-xymax,xymax,100);
y = linspace(-xymax,xymax,100);
% note that x and y don't include 0
% [X,Y] = meshgrid(x(x<-1 | x>1),y(y<-1 | y>1));
[X,Y] = meshgrid(x,y);
R = sqrt(X.^2 + Y.^2);
sin_th = Y./R;
cos_th = X./R;
U = 1;
a = 1;
psi = U*(R - a*a./R).*sin_th;
% mask the inner part with nans:
psi((Y>0 & psi<0) | (Y<0 & psi>0)) = nan;
contour(X,Y,psi,[-3:0.25:3],'-b');
% draw a circle:
rectangle('Position', [-1 -1 2 2],'Curvature',[1 1],'EdgeColor','r')
axis equal
You can try also changing directly X and Y (instead of Y and psi):
psi(Y>-1 & X>-1 & Y<1 & X<1) = nan;
but the result is a bit different.
This is counter-intuitive, but the rectangle function can be used to draw a circle!
hold on
rectangle('Position',[-R,-R,2*R,2*R],'Curvature',[1,1],'FaceColor',[1 1 0])
Feel free to play around with the line properties too ('EdgeColor' and 'LineWidth')
https://www.mathworks.com/help/matlab/ref/rectangle.html

How to plot a filled circle?

The below code plots circles in Matlab. How can I specify the MarkerEdgeColor and MarkerFaceColor in it.
function plot_model
exit_agents=csvread('C:\Users\sony\Desktop\latest_mixed_crowds\December\exit_agents.csv');
%scatter(exit_agents(:,2),exit_agents(:,3),pi*.25^2,'filled');
for ii =1:size(exit_agents,1),
circle(exit_agents(ii,2),exit_agents(ii,3),0.25);
end
end
function h = circle(x,y,r)
hold on
th = 0:pi/50:2*pi;
xunit = r * cos(th) + x;
yunit = r * sin(th) + y;
h = plot(xunit, yunit);
hold off
end
Using plot and scatter scales them weirdly when zooming. This is not what I wish for.
There are various options to plot circles. The easiest is, to actually plot a filled rectangle with full curvature:
%// radius
r = 2;
%// center
c = [3 3];
pos = [c-r 2*r 2*r];
r = rectangle('Position',pos,'Curvature',[1 1], 'FaceColor', 'red', 'Edgecolor','none')
axis equal
With the update of the graphics engine with R2014b this is really smooth:
If you have an older version of Matlab than R2014b, you will need to stick with your trigonometric approach, but use fill to get it filled:
%// radius
r = 2;
%// center
c = [3 3];
%// number of points
n = 1000;
%// running variable
t = linspace(0,2*pi,n);
x = c(1) + r*sin(t);
y = c(2) + r*cos(t);
%// draw filled polygon
fill(x,y,[1,1,1],'FaceColor','red','EdgeColor','none')
axis equal
The "resolution" can be freely scaled by the number of points n.
Your function could then look like
function h = circle(x,y,r,MarkerFaceColor,MarkerEdgeColor)
hold on
c = [x y];
pos = [c-r 2*r 2*r];
r = rectangle('Position',pos,'Curvature',[1 1], ...
'FaceColor', MarkerFaceColor, 'Edgecolor',MarkerEdgeColor)
hold off
end

fill function in MATLAB

I'm having issues unterstanding the function fill in MATLAB , I have a PSD of a file the I want to change it background like :
[xPSD,f] = pwelch(x,hanning(4096),2048,4096*2 ,fs);
plot(f,10*log10(xPSD));
x= f(100:150);
y= 10*log10(xPSD(100:150))
fill(x,y,'y')
the result is in the right direction but not what I need :
I would like get the color tell x axis like :
is their a way to do this
A working solution is:
[xPSD,f] = pwelch(x,hanning(4096),2048,4096*2 ,fs);
plot(f,10*log10(xPSD));
hold on
x= f(100:150);
y= 10*log10(xPSD(100:150));
yMax = ylim;
yMax = yMax(2);
x = x'; % Use this line only in the case that the size(x, 1) > 1
X = [x fliplr(x)];
Y = [y' ones(1, length(y)) .* yMax];
fill(X, Y, 'y')
What you were missing is that fill method looks for an area to fill. In the above code the area is defined by pairs of points. That, for the first (i.e. lower part) of the area we have the x vector and the y points. The second area (i.e. the upper part) is defined by the reversed vector x (image your pencil to first starting drawing towards rights for the lower part and then for the upper going left) and the points of the upper limit of your axes.
Edit:
Minimal example with the handel data from MATLAB:
load handel;
x = y; % Just to be consistent with the OP
fs = Fs; % Just to be consistent with the OP
[xPSD,f] = pwelch(x,hanning(4096),2048,4096*2 ,fs);
plot(f,10*log10(xPSD));
hold on
x= f(100:150);
y= 10*log10(xPSD(100:150));
yMax = ylim;
yMax = yMax(2);
x = x'; % Use this line only in the case that the size(x, 1) > 1
X = [x fliplr(x)];
Y = [y' ones(1, length(y)) .* yMax];
fill(X, Y, 'y')
xlim([0 200]) % To focus on the result
The result is:
Yes, there is always a way ;)
In your case, you simply need to add two points in x and y that go to the top boudary of the plot:
x = f(100:150);
y = 10*log10(xPSD(100:150))
% Add two points
Y = ylim;
x = [x(1) ; x(:) ; x(end)];
y = [Y(2) ; y(:) ; Y(2)];
% Display filled area
fill(x,y,'y')
Best,