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 am trying to create a figure showing the solution I obtained through Jacobi iteration along with the true solution, as well as the error of the Jacobi solution.
The figure I'm trying to create should consist of two plots.
I used the subplot command, to split the figure into
an upper and lower axes and I wrote the for loop that calculates the Jacobi iterations and the error. The loop is going to iterate 400 times using x0 as the initial guess. Before this, I calculated the true solution to the system Ax = b.
N = 30;
iter = 400;
A = toeplitz([-2 1 zeros(1, N-2)], [-2 1 zeros(1, N-2)]);
bk = ones(N,1);
for jj = 1:N
bk(jj) = cos(5*jj) + (1/2)*sin(7*jj);
end
x = A\bk;
D = diag(diag(A));
T = A - D;
x0 = zeros(N,1);
error = zeros(iter,1);
M = -D\T;
g = D\bk;
for nn = 1:iter
x0 = M*x0 + g;
error(nn) = norm(x - x0,2);
end
subplot(2,1,1)
plot(x0(1:N,1),'ro');
ylabel('Solution','FontSize',22);
title('Solution by Jacobi Iteration','FontSize',22);
xlim([0 pi]);
ylim([-5 5]);
xticks(0:0.5:3);
yticks(-5:5:5);
subplot(2,1,2)
plot(error(1:N),'ro')
ylabel('Error','FontSize',22);
xlabel('t','FontSize',22);
xlim([0 pi]);
ylim([0 0.1]);
xticks(0:0.5:3);
yticks(0:0.05:0.1);
The upper window should show the true solution in red circles connected by solid lines. The lower window show show the error as red
circles connected by dotted lines. When I ran my code, only 3 red circles appeared in the upper window and nothing was plotted in the lower window. I'm still bad at plotting iterations of a loop. Can someone help me with plotting the solutions and errors I calculated?
The xlim and ylim statements are not representative of the data.
x0 and x have N elements (30 here), and the elements of x and x0 span -2 to 2 in this setup.
error has iter elements (400 here), and the elements of error go from 4 to about 0.01.
For these plots, the element index maps to the horizontal x-axis, and their values to the y-axis. I think this plot setup should give you the result you desire (I probably changed more than actually needed):
subplot(2,1,1);
plot(1:N, x0(1:N,1), 'ro', 1:N, x,'k+');
title('Solution by Jacobi Iteration','FontSize',22);
ylabel('Solution','FontSize',22);
xlim([1, N]);
ylim([-3, 3]);
xticks(1:N);
yticks(-3:0.5:3);
subplot(2,1,2)
semilogy(1:iter, error(1:iter),'ro')
ylabel('Error','FontSize',22);
xlabel('t','FontSize',22);
xlim([1 iter]);
ylim([0 4]);
xticks(0:25:400);
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');
I am currently working on a project simulating the movement of two spacecraft and a moon (Phobos) around Mars. A MATLAB tool called SPICE gives me an array with the x, y and z distances and I have used these to plot the orbit which works fine. Now I want to get markers for each of the spacecraft and Phobos to see when they flyby each other. I got the markers working but not at the same time, they run after each other. I found an example on youtube so it must be possible but he has not released the code how to do it (https://www.youtube.com/watch?v=nArR2P0o4r4).
This is the code I have:
a = position_MEX_Mars(1,:);
b = position_MEX_Mars(2,:);
c = position_MEX_Mars(3,:);
k = position_MAVEN_Mars(1,:);
l = position_MAVEN_Mars(2,:);
m = position_MAVEN_Mars(3,:);
x = position_Phobos_Mars(1,:);
y = position_Phobos_Mars(2,:);
z = position_Phobos_Mars(3,:);
ah = axes;
set(ah,'XLim',[min(x) max(x)],'YLim',[min(y) max(y)],...
'ZLim',[min(z) max(z)]);
plot3(0,0,0,'ro-',x,y,z,a,b,c,k,l,m);
grid on;
hold on;
hpoint = line('XData', 0,'YData', 0,'ZData', 0,'Color','black','Marker',...
'o','MarkerSize',10);
ht = hgtransform('parent',ah);
set(hpoint,'Parent',ht);
for i =2:length(x)
trans = makehgtform('translate',[x(i) y(i) z(i)]);
set(ht,'Matrix',trans);
pause(0.001);
end
This will run a nice animated plot of the trajectory of Phobos in time but only Phobos and not simultaneous with MEX and MAVEN (spacecraft from ESA and NASA).
I tried this but does not work:
a = position_MEX_Mars(1,:);
b = position_MEX_Mars(2,:);
c = position_MEX_Mars(3,:);
k = position_MAVEN_Mars(1,:);
l = position_MAVEN_Mars(2,:);
m = position_MAVEN_Mars(3,:);
x = position_Phobos_Mars(1,:);
y = position_Phobos_Mars(2,:);
z = position_Phobos_Mars(3,:);
ah = axes;
set(ah,'XLim',[min(x) max(x)],'YLim',[min(y) max(y)],...
'ZLim',[min(z) max(z)]);
plot3(0,0,0,'ro-',x,y,z,a,b,c,k,l,m);
grid on;
hold on;
hpoint = line('XData', 0,'YData', 0,'ZData', 0,'Color','black','Marker',...
'o','MarkerSize',10);
ht = hgtransform('parent',ah);
set(hpoint,'Parent',ht);
for i =2:length(x)
trans1 = makehgtform('translate',[x(i) y(i) z(i)]);
set(ht,'Matrix',trans1);
trans2 = makehgtform('translate',[a(i) b(i) c(i)]);
set(ht,'Matrix',trans2);
pause(0.001);
end
I also tried merging the arrays so that it plots them each one step after each other but that makes the animation not smooth and is not satisfying for the project.
a = position_MEX_Mars(1,:);
b = position_MEX_Mars(2,:);
c = position_MEX_Mars(3,:);
k = position_MAVEN_Mars(1,:);
l = position_MAVEN_Mars(2,:);
m = position_MAVEN_Mars(3,:);
x = position_Phobos_Mars(1,:);
y = position_Phobos_Mars(2,:);
z = position_Phobos_Mars(3,:);
tempx = [position_MEX_Mars(1,:); position_Phobos_Mars(1,:); position_MAVEN_Mars(1,:)];
xt = tempx(:);
tempy = [position_MEX_Mars(2,:); position_Phobos_Mars(2,:); position_MAVEN_Mars(2,:)];
yt = tempy(:);
tempz = [position_MEX_Mars(3,:); position_Phobos_Mars(3,:); position_MAVEN_Mars(3,:)];
zt = tempz(:);
ah = axes;
set(ah,'XLim',[min(x) max(x)],'YLim',[min(y) max(y)],...
'ZLim',[min(z) max(z)]);
plot3(0,0,0,'ro-',x,y,z,a,b,c,k,l,m);
grid on;
hold on;
hpoint = line('XData', 0,'YData', 0,'ZData', 0,'Color','black','Marker',...
'o','MarkerSize',10);
ht = hgtransform('parent',ah);
set(hpoint,'Parent',ht);
for i =2:length(x)
trans = makehgtform('translate',[xt(i) yt(i) zt(i)]);
set(ht,'Matrix',trans);
pause(0.001);
end
I think I am close but I seem to be missing something and my knowledge of MATLAB is not that great yet. I hope you can help me out.
Cheers Jeroen
Here's a simplified (and not physically correct) example that could perhaps be useful:
t = linspace(0,2,1000); %// time parameter
x1 = 10*cos(2*pi*t+1);
y1 = 5*sin(2*pi*t+1); %// trajectory of object 1
x2 = 2*cos(6*pi*t-2);
y2 = 3*sin(6*pi*t-2); %// trajectory of object 1
plot(x1,y1,'color',[.5 .5 .5]); %// plot trajectory of object 1
hold on
plot(x2,y2,'color',[.5 .5 .5]); %// plot trajectory of object 2
h1 = plot(x1(1),y1(1),'ro'); %// plot initial position of object 1
h2 = plot(x2(1),y2(1),'b*'); %// plot initial position of object 2
axis([-12 12 -12 12]) %// freeze axis size
grid on
for n = 1:numel(t)
set(h1, 'XData', x1(n), 'YData', y1(n)); %// update position of object 2
set(h2, 'XData', x2(n), 'YData', y2(n)); %// update position of object 2
drawnow %// refresh figure
end
The thing that you tries to do is not really as easy as you think. The main issue is that you need to update everything at the same time. This have been implemented in several ways during the years. One way to do this is by using a so called a double buffer.
This means that you have two "surfaces" to paint on. In matlab this is translated to 2 axes (or 2 figures maybe). However, you do only have one axes visible at the same time. This means that you will have time to paint everything on the "hidden surface" before displaying the content. When you are done with everything you need you just switch which surface being visible.
It is possible that this can be done in a simpler way, but I am not familiar with the hgtransfrom functions in matlab.
EDIT
This is an example how it can be done
function test()
fig = figure;
ax1 = axes;
plot(1:10);
ax2 = axes;
plot(1:10,'r');
setVisibility(ax2,'off');
pause(1);
for k = 1:5
setVisibility(ax2,'on');
setVisibility(ax1,'off');
pause(1);
setVisibility(ax1,'on');
setVisibility(ax2,'off');
pause(1);
end
function setVisibility(ax, visibility)
set(ax, 'visible', visibility)
set(findall(ax), 'visible', visibility)
I would like to make a plot then rotate the x-y axes by an angle;
then make the same plot again on the rotated axes, then rotate axes again for the next similar plot
Something like this:
hold all;
for k= 0:1:10
% rotate-axis-about-origin(angle * k)
plot(XY(:,1),XY(:,2));
end
Is there any way to achieve what I am proposing?
Use a rotation matrix inside the loop:
hold all;
% test vector and matrix
x = (1:10)';
y = x.^2;
XY0 = [x y];
angle = 1/180*pi; % 1 degree
for k= 0:1:10
% rotate-axis-about-origin(angle * k)
rot = [cos(angle*k) sin(angle*k);-sin(angle*k) cos(angle*k)];
XY = XY0*rot;
plot(XY(:,1),XY(:,2));
end
XY0 is the original matrix and XY varies each step.
Hope this is what you are looking for.
You can do that by rolling the camera at each step via camroll. Here's a toy working example for plotting sine:
hold all
x = -3:0.01:3;
y = sin(x);
angle = 1; % in degrees
for k = 1:90 % 90 steps
plot(x,y, 'k');
camroll(angle); % roll 'angle' degrees at each step
drawnow
pause(0.05)
end