I am trying to plot the DC component of the Fourier Series together with the harmonics in the first panel. But the first panel only outputs the harmonics. Please help me in solving this one. Below is my code and output plot.
n = 30;
x = (0:300)/100;
xx = 2*x;
ao = 1/2; %DC component
f = ones(1,301)*ao;
for i = 1:2:n
bn = 2/pi/i;
bnx = bn*sin(2*pi*i*x);
f = f + bnx;
subplot(1,2,1)
plot(xx,ao) %Plotting of DC component
hold on
plot(xx,bnx)
hold on
subplot(1,2,2)
plot(xx,f)
hold off
end
The problem is the line
plot(xx,ao) %Plotting of DC component
Here xx is a vector and ao is a number. From the documentation, in this case the plot function plots discrete points; and these are not even visible because no marker has been specified.
To obtain a horizontal line of height ao, you need to replace the above by the following, so that both inputs to plot are vectors:
plot(xx,repmat(ao,size(xx)))
In addition, it would be better to move this line of code, together with subplot(1,2,1) and hold on, before the loop, to plot the DC component only once:
n = 30;
x = (0:300)/100;
xx = 2*x;
ao = 1/2; %DC component
f = ones(1,301)*ao;
subplot(1,2,1)
plot(xx,repmat(ao,size(xx))) %Plotting of DC component
hold on
for i = 1:2:n
bn = 2/pi/i;
bnx = bn*sin(2*pi*i*x);
f = f + bnx;
subplot(1,2,1)
plot(xx,bnx)
subplot(1,2,2)
plot(xx,f)
hold off
end
Related
I made two 3D plots on the same axis. now I desire to give them different colors for easy identification. How do I do this coloring? The MATLAB code is shown below.
tic
Nx = 50;
Ny = 50;
x = linspace(0,1,Nx);
y = linspace(0,0.5,Ny);
[X,Y] = meshgrid(x,y);
[M,N] = size(X);
for m=1:M
for n=1:N
%get x,y coordinate
x_mn = X(m,n);
y_mn = Y(m,n);
%%% X=D2 and Y=D1
%Check if x_mn and y_mn satisfy requirement
if(x_mn >= y_mn)
%evaluate function 1
Z(m,n) = (x_mn^2 - 2*x_mn*y_mn + y_mn^2);
Z_1(m,n) = (x_mn^2);
elseif(x_mn < y_mn)
%evaluate function 2
Z(m,n) = 0;
Z_1(m,n) = (x_mn^2);
%% Z(m,n) = 2*(2*x_mn*y_mn + y_mn - y_mn^2 - 2*x_mn);
else
Z(m,n) = 0;
end
end
end
%Plot the surface
figure
surf(X,Y,Z) %first plot
surfc(X,Y,Z)
hold on
surf(X,Y,Z_1) %second plot
xlabel('Dm');
ylabel('D');
zlabel('pR');
grid on
shading interp
toc
disp('DONE!')
How can I create two differently colored surfaces?
figure
surf(X,Y,Z) %first plot
surfc(X,Y,Z)
hold on
surf(X,Y,Z_1)
Your surfc() call actually overwrites your surf() call, is this intended?
As to your colour: the documentation is a marvellous thing:
surfc(X,Y,Z,C) additionally specifies the surface color.
In other words: just specify the colour as you want it. C needs to be a matrix of size(Z) with the desired colours, i.e. set all of them equal to create an monocoloured surface:
x = 1:100;
y = 1:100;
z = rand(100);
figure;
surfc(x,y,z,ones(size(z)))
hold on
surfc(x,y,z+6,ones(size(z))+4)
Results in (MATLAB R2007b, but the syntax is the same nowadays)
I need to extract the isoline coordinates of a 4D variable from a 3D surface defined using a triangulated mesh in MATLAB. I need the isoline coordinates to be a ordered in such a manner that if they were followed in order they would trace the path i.e. the order of the points a 3D printer would follow.
I have found a function that can calculate the coordinates of these isolines (see Isoline function here) but the problem is this function does not consider the isolines to be joined in the correct order and is instead a series of 2 points separated by a Nan value. This makes this function only suitable for visualisation purposes and not the path to follow.
Here is a MWE of the problem of a simplified problem, the surface I'm applying it too is much more complex and I cannot share it. Where x, y and z are nodes, with TRI providing the element connectivity list and v is the variable of which I want the isolines extracted from and is not equal to z.
If anyone has any idea on either.....
A function to extract isoline values in the correct order for a 3D tri mesh.
How to sort the data given by the function Isoline so that they are in the correct order.
.... it would be very much appreciated.
Here is the MWE,
% Create coordinates
[x y] = meshgrid( -10:0.5:10, -10:0.5:10 );
z = (x.^2 + y.^2)/20; % Z height
v = x+y; % 4th dimension value
% Reshape coordinates into list to be converted to tri mesh
x = reshape(x,[],1); y = reshape(y,[],1); z = reshape(z,[],1); v = reshape(v,[],1);
TRI = delaunay(x,y); % Convertion to a tri mesh
% This function calculates the isoline coordinates
[xTows, yTows, zTows] = IsoLine( {TRI,[x, y, z]}, v, -18:2:18);
% Plotting
figure(1); clf(1)
subplot(1,2,1)
trisurf(TRI,x,y,z,v)
hold on
for i = 1:size(xTows,1)
plot3( xTows{i,1}, yTows{i,1}, zTows{i,1}, '-k')
end
hold off
shading interp
xlabel('x'); ylabel('y'); zlabel('z'); title('Isolines'), axis equal
%% This section is solely to show that the isolines are not in order
for i = 1:size(xTows,1)
% Arranging data into colums and getting rid of Nans that appear
xb = xTows{i,1}; yb = yTows{i,1}; zb = zTows{i,1};
xb = reshape(xb, 3, [])'; xb(:,3) = [];
yb = reshape(yb, 3, [])'; yb(:,3) = [];
zb = reshape(zb, 3, [])'; zb(:,3) = [];
subplot(1,2,2)
trisurf(TRI,x,y,z,v)
shading interp
view(2)
xlabel('x'); ylabel('y'); zlabel('z'); title('Plotting Isolines in Order')
axis equal; axis tight; hold on
for i = 1:size(xb,1)
plot3( [xb(i,1) xb(i,2)], [yb(i,1) yb(i,2)], [zb(i,1) zb(i,2)], '-k')
drawnow
end
end
and here is the function Isoline, which I have slightly adpated.
function [xTows, yTows, zTows] = IsoLine(Surf,F,V,Col)
if length(Surf)==3 % convert mesh to triangulation
P = [Surf{1}(:) Surf{2}(:) Surf{3}(:)];
Surf{1}(end,:) = 1i;
Surf{1}(:,end) = 1i;
i = find(~imag(Surf{1}(:)));
n = size(Surf{1},1);
T = [i i+1 i+n; i+1 i+n+1 i+n];
else
T = Surf{1};
P = Surf{2};
end
f = F(T(:));
if nargin==2
V = linspace(min(f),max(f),22);
V = V(2:end-1);
elseif numel(V)==1
V = linspace(min(f),max(f),V+2);
V = V(2:end-1);
end
if nargin<4
Col = 'k';
end
H = NaN + V(:);
q = [1:3 1:3];
% -------------------------------------------------------------------------
% Loop over iso-values ----------------------------------------------------
xTows = [];
yTows = [];
zTows = [];
for k = 1:numel(V)
R = {[],[]};
G = F(T) - V(k);
C = 1./(1-G./G(:,[2 3 1]));
f = unique(T(~isfinite(C))); % remove degeneracies by random perturbation
F(f) = F(f).*(1+1e-12*rand(size(F(f)))) + 1e-12*rand(size(F(f)));
G = F(T) - V(k);
C = 1./(1-G./G(:,[2 3 1]));
C(C<0|C>1) = -1;
% process active triangles
for i = 1:3
f = any(C>=0,2) & C(:,i)<0;
for j = i+1:i+2
w = C(f,q([j j j]));
R{j-i} = [R{j-i}; w.*P(T(f,q(j)),:)+(1-w).*P(T(f,q(j+1)),:)];
end
end
% define isoline
for i = 1:3
X{i} = [R{1}(:,i) R{2}(:,i) nan+R{1}(:,i)]';
% X{i} = [R{1}(:,i) R{2}(:,i)]'; % Changed by Matt
X{i} = X{i}(:)';
end
% plot isoline
if ~isempty(R{1})
% hold on
% H(k) = plot3(X{1},X{2},X{3},Col);
% Added by M.Thomas
xTows{k,1} = X{1};
yTows{k,1} = X{2};
zTows{k,1} = X{3};
end
end
What you will notice is that the isolines (xTows, yTows and zTows) are not in order there "jump around" when plotted sequentially. I need to sort the tows so that they give a smooth plot in order.
I have created some MatLab code that plots a plane wave using two different expressions that give the same plane wave. The first expression is in Cartesian coordinates and works fine. However, the second expression is in polar coordinates and when I calculate the plane wave in this case, the plot is distorted. Both plots should look the same. So what am I doing wrong in transforming to/from polar coordinates?
function Plot_Plane_wave()
clc
clear all
close all
%% Step 0. Input paramaters and derived parameters.
alpha = 0*pi/4; % angle of incidence
k = 1; % wavenumber
wavelength = 2*pi/k; % wavelength
%% Step 1. Define various equivalent versions of the incident wave.
f_u_inc_1 = #(alpha,x,y) exp(1i*k*(x*cos(alpha)+y*sin(alpha)));
f_u_inc_2 = #(alpha,r,theta) exp(1i*k*r*cos(theta-alpha));
%% Step 2. Evaluate the incident wave on a grid.
% Grid for field
gridMax = 10;
gridN = 2^3;
g1 = linspace(-gridMax, gridMax, gridN);
g2 = g1;
[x,y] = meshgrid(g1, g2);
[theta,r] = cart2pol(x,y);
u_inc_1 = f_u_inc_1(alpha,x,y);
u_inc_2 = 0*x;
for ir=1:gridN
rVal = r(ir);
for itheta=1:gridN
thetaVal = theta(itheta);
u_inc_2(ir,itheta) = f_u_inc_2(alpha,rVal,thetaVal);
end
end
%% Step 3. Plot the incident wave.
figure(1);
subplot(2,2,1)
imagesc(g1(1,:), g1(1,:), real(u_inc_1));
hGCA = gca; set(hGCA, 'YDir', 'normal');
subplot(2,2,2)
imagesc(g1(1,:), g1(1,:), real(u_inc_2));
hGCA = gca; set(hGCA, 'YDir', 'normal');
end
Your mistake is that your loop is only going through the first gridN values of r and theta. Instead you want to step through the indices of ix and iy and pull out the rVal and thetaVal of the matrices r and theta.
You can change your loop to
for ix=1:gridN
for iy=1:gridN
rVal = r(ix,iy); % Was equivalent to r(ix) outside inner loop
thetaVal = theta(ix,iy); % Was equivalent to theta(iy)
u_inc_2(ix,iy) = f_u_inc_2(alpha,rVal,thetaVal);
end
end
which gives the expected graphs.
Alternatively you can simplify your code by feeding matrices in to your inline functions. To do this you would have to use an elementwise product .* instead of a matrix multiplication * in f_u_inc_2:
alpha = 0*pi/4;
k = 1;
wavelength = 2*pi/k;
f_1 = #(alpha,x,y) exp(1i*k*(x*cos(alpha)+y*sin(alpha)));
f_2 = #(alpha,r,theta) exp(1i*k*r.*cos(theta-alpha));
% Change v
f_old = #(alpha,r,theta) exp(1i*k*r *cos(theta-alpha));
gridMax = 10;
gridN = 2^3;
[x,y] = meshgrid(linspace(-gridMax, gridMax, gridN));
[theta,r] = cart2pol(x,y);
subplot(1,3,1)
contourf(x,y,real(f_1(alpha,x,y)));
title 'Cartesian'
subplot(1,3,2)
contourf(x,y,real(f_2(alpha,r,theta)));
title 'Polar'
subplot(1,3,3)
contourf(x,y,real(f_old(alpha,r,theta)));
title 'Wrong'
I am trying to plot the elliptical trajectory of a particle, but my matlab code runs and gives me warning that I m trying to plot imaginary values. How can I remove this error?
My Matlab code is as follows:
% plot of trajectory of the particle in flexural gravity wave
U =5;
t=1;
y1=0;
h=50;
k=2*pi/100;
w=pi;
X= (-80*pi:pi:80*pi);
Y= (-80*pi:pi:80*pi);
H=1;
A= (H/2)*cosh(k*(h+y1))/sinh(k*h);
B= (H/2)*sinh(k*(h+y1))/sinh(k*h);
Y = B.* ((1-((X-U*t)./A).^2).^(1/2));
plot(X,Y);
xlabel('X');
ylabel('Y');
The warning matlab shows is:
Warning: Imaginary parts of complex X and/or Y arguments ignored
Please help me out with this.
If you want to plot imaginary number only,
Please change the code, plot(X,Y); as plot(X,imag(Y)).
In case of real value, plot(X,real(Y)).
If you are interested in magnitude of complex number, plot(X,abs(Y)).
I got the answer to my question.
I can plot it by using general coordinates of the ellipse, ie, using x=acos(t) and y=asin(t). and that really worked.
% plot of trajectory of the particle in flexural gravity wave
U = 5;
t = 1;
y1 = 0;
h = 50;
k = 2*pi/100;
w = pi;
x0 = U*t;
y0 = 0;
H = 1;
A = (H/2)*cosh(k*(h+y1))/sinh(k*h);
B = (H/2)*sinh(k*(h+y1))/sinh(k*h);
z = -2*pi:0.01:2*pi;
X = x0 + A*cos(z);
Y = y0 + B*sin(z);
plot(X,Y);
xlabel('X');
ylabel('Y');
if zeta < 1
omegad = omegan*sqrt(1-zeta^2);
c1 = y0;
c2 = ydot0/(omegan);
p1 = (-zeta*omegan)+(omegan)*sqrt((zeta^2)-1);
p2 = (-zeta*omegan)-(omegan)*sqrt((zeta^2)-1);
x = c1*exp(p1*t)+c2*exp(p2*t);
xdot = p1*c1*exp(p1*t)+p2*c2*exp(p2*t);
set(handles.omegad_output,'String',omegad);
elseif zeta == 1
omegad = omegan*sqrt(1-zeta^2);
c1 = y0;
c2 = ydot0/(omegan);
x = c1*exp(-omegan.*t)+c2.*t*exp(-omegan.*t);
xdot = -omegan*c1*exp(-omegan.*t)-omegan*c2*t*exp(-omegan*t)+t*exp(-omegan*t);
set(handles.omegad_output,'String',omegad);
else
omegad = omegan*sqrt(1-zeta^2);
c1 = y0;
c2 = (ydot0+zeta*omegan*y0)/omegad;
x = exp(-zeta*omegan.*t).*(c1*cos(omegad.*t)+c2*sin(omegad.*t));
A = -zeta*omegan*exp(-zeta*omegan.*t);
B = c1*cos(omegad.*t)+c2*sin(omegad.*t);
C = exp(-zeta*omegan.*t);
D = -c1*omegad*sin(omegad.*t)+c2*omegad*cos(omegad.*t);
xdot = A.*B+C.*D;
set(handles.omegad_output,'String',omegad);
end
% Create Amplitude plot in proper axes
plot(handles.amplitude_axes,t,x)
set(handles.amplitude_axes,'XMinorTick','on')
grid on
% Create Velocity plot in proper axes
plot(handles.velocity_axes,t,xdot)
set(handles.velocity_axes,'XMinorTick','on')
grid on
Im constructing a GUI and here is the plot button callback function. I have the above code and when I plot it the gridlines only come up for the Amplitude plot and not the Velocity plot, how do I have the gridlines show up for both plots.
Replace grid on with:
grid (handles.velocity_axes,'on')
grid (handles.amplitude_axes,'on')
This is because the command form of grid works only on the current axes gca. Plotting in specific axes won't make those axes current, thus the second grid on will apply again on the current axes, which happens to be the Amplitude plot.