Mesh Plot Problems in Matlab - matlab

I want to draw a meshc contour plot, but the contour is not being drawn as I want.
x = linspace(P(1),P(2)); %// x axis
y = linspace(P(3),P(4)); %// y axis
[X1 Y1] = meshgrid(x,y); %// all combinations of x, y
%[X1,Y1] = meshgrid(1:.125:3);
Z1 = mvnpdf([X1(:) Y1(:)],mu,sigma); %// compute Gaussian pdf
Z2 = reshape(Z1,size(X1)); %// put into same size as X, Y
meshc(X1,Y1,Z2);
%axis([1 3 1 3 -5 10]);
axis([P(1) P(2) P(3) P(4) -5 10])
The code above draws it this way:
But I want it to be this way:
How could I do this?

To get desired distance between the plots you can just subtract some number from the Z2 matrix. I cannot figure out why Matlab divides the plots in this way, but it works:
P = [1 3 1 3];
mu = [2 1.1];
sigma = [.09 .003; ...
.003 .002];
x = linspace(P(1),P(2)); %// x axis
y = linspace(P(3),P(4)); %// y axis
[X1 Y1] = meshgrid(x,y); %// all combinations of x, y
Z1 = mvnpdf([X1(:) Y1(:)],mu,sigma); %// compute Gaussian pdf
Z2 = reshape(Z1,size(X1)); %// put into same size as X1, Y1
Z2 = Z2 - 0.01;
meshc(X1,Y1,Z2);
axis([P(1) P(2) P(3) P(4) -5 10])
Maybe you need to play with other numbers to get a desired result. In my example I subtracted a small number, in order to avoid changing of the pdf-plot range.

Related

Find the third set of coordaintes (x3 y3) of right angle triangle - Matlab

How can I find the third set of coordinates (X3 Y3) of right angle triangle based on the distances between all coordinates and the other two set of coordinates (X1 Y1; X2 Y2)
Code:
clc;
clear all;
close all;
axis on;
%Example of initial parameters
X1 = 0
Y1 = 2
X2 = 6
Y2 = 7
DX2Y2X3Y3 = 10
%Draw line
line([X1, X2], [Y1, Y2])
text(X1,Y1-0.05,strcat(string(X1),",",string(Y1)))
text(X2,Y2-0.05,strcat(string(X2),",",string(Y2)))
%Calculations
DX1Y1X2Y2 = sqrt((X2-X1)^2+(Y2-Y1)^2) %distance x1,y1 x2,y2
DX1Y1X3Y3 = sqrt(DX2Y2X3Y3+DX1Y1X2Y2)%distance x1,y1 x3,y3 based on Pythagoras
So assuming you have
P1 = [X1 Y1]
P2 = [X2 Y2]
Assertion that the angle at P2 is 90
Length DX2Y2X3Y3
Then we can do the following:
vP1P2 = [X2; Y2] - [X1; Y1]; % Direction vector
vP2P3 = [1; -1] .* flipud(vP1P2); % Negative inverse for rightangle
vP2P3 = vP2P3 ./ sqrt(vP2P3(1)^2 + vP2P3(2)^2); % Scale to unit length
P3 = [X2; Y2] - DX2Y2X3Y3 .* vP2P3; % Calc P3 from P2 + vP2P3
X3 = P3(1); Y3 = P3(2); % Break down into coordinates
line([X2, X3], [Y2, Y3])
line([X1, X3], [Y1, Y3])
axis equal % to make the plot clearer
Note that there are two valid solutions to this problem, reflected in the line from P1 to P2. The choice of direction (+ve / -ve) for vP2P3 will dictate which solution you get.
This code gives the following output:

Multiple colors in the same line

I would like to plot a sine curve in Matlab. But I want it blue for the positive values and red for the negative values.
The following code just makes everything red...
x = [];
y = [];
for i = -180 : 180
x = [x i];
y = [y sin(i*pi/180)];
end
p = plot(x, y)
set(p, 'Color', 'red')
Plot 2 lines with different colours, and NaN values at the positive/negative regions
% Let's vectorise your code for efficiency too!
x = -pi:0.01:pi; % Linearly spaced x between -pi and pi
y = sin(x); % Compute sine of x
bneg = y<0; % Logical array of negative y
y_pos = y; y_pos(bneg) = NaN; % Array of only positive y
y_neg = y; y_neg(~bneg)= NaN; % Array of only negative y
figure; hold on; % Hold on for multiple plots
plot(x, y_neg, 'b'); % Blue for negative
plot(x, y_pos, 'r'); % Red for positive
Output:
Note: If you're happy with scatter plots, you don't need the NaN values. They just act to break the line so you don't get join-ups between regions. You could just do
x = -pi:0.01:pi;
y = sin(x);
bneg = y<0;
figure; hold on;
plot(x(bneg), y(bneg), 'b.');
plot(x(~bneg), y(~bneg), 'r.');
Output:
This is so clear because my points are only 0.01 apart. Further spaced points would appear more like a scatter plot.

How can I plot a surface generated by a function f(x,y) where the values x and y are subject to constraints?

I'm new to Matlab and I have a function
and
How can I plot:
Define your X and Y in a linear array
X = linspace(-2, 2, 1000);
Y = linspace(-2, 2, 1000);
Mesh them so you have a grid of x and y
[x,y] = meshgrid(X,Y);
Get the value for your function
f = sqrt(x.^2 + y.^2);
Define your domain
D = (1 <= x.^2 + y.^2);
Set everything outside your domain to nan's so it won't plot
f(~D) = nan;
Plot the surface
surf(x,y,f, 'linestyle', 'none')

Draw the vector w as well as the projection of another vector onto w

How can I plot the vector w with the projected data onto this vector?
Here is the code - and my trials to plot the weight vector with y1 and y2.
x1=[1 2;2 3;3 3;4 5;5 5] % the first class 5 observations
x2=[1 0;2 1;3 1;3 2;5 3;6 5]
m1 = mean(x1);
m2 = mean(x2);
m = m1 + m2;
d1=x1-repmat(m1,5,1);
d2=x2-repmat(m2,6,1);
c = 0.5.*m;
Sw1 = d1'*d1;
Sw2 = d2'*d2;
Sw = Sw1 + Sw2;
invSw = inv(Sw);
w= invSw*(m1-m2)' %this is my vector projected
scatter(x1(:,1), x1(:,2), 10, 'ro');
hold on;
scatter(x2(:,1), x2(:,2), 10,'bo');
%this is how i plot the decision boundary, but it doesn't seems correct.
quiver(c(1,1), c(1,2), 1, -w(1,1)/w(2,1));
quiver(c(1,1), c(1,2), -1, w(1,1)/w(2,1));
auxw= w/norm(w);
plot([0 auxw(1)], [0 auxw(2)])
hold off;
figure;
y1 = x1*w;
y2 = x2*w;
hist([y1' y2'])
You are very close. You've only calculated (or tried to calculate) the scalar projection or the amount of scale you apply to each vector in order to project each vector in x1 and x2 onto w though what you have is incomplete. If you recall from linear algebra, to determine the scalar projection between two vectors a and b, or the scalar projection of b onto a, the formula is:
Source: Oregon State Mathematics: Calculus for Undergraduates
In our case, a would be w and b would be each of the vectors seen in x1 and x2. I'm assuming each row of these matrices is a vector. The scalar projections are seen in y1 and y2. You need to compute the vector projection, which is defined as taking the scalar projections and multiplying by the unit vectors of a, or simply:
Source: Oregon State Mathematics: Calculus for Undergraduates
Therefore, the calculation of the scalar projections in y1 and y2 are incorrect. You have to multiply by the normalized vector w, then when you find these scalar projection values, you multiply each of these scalar values with the corresponding normalized vector w. However, plotting these all simultaneously on a graph will be confusing. You will have many lines that will overlap onto the original vector w so what I did was I looped through plotting w, a vector in either x1 or x2 and the corresponding projected vector. Each time we loop, we pause and show the data then clear the figure and start again.
As such, I've added and changed the following to your code.
%// Your data
w = [-0.7936; 0.8899];
x1 = [1 2; 2 3; 3 3; 4 5; 5 5];
x2 = [1 0; 2 1; 3 1; 3 2; 5 3; 6 5];
%// Compute scalar projection
auxw = w/norm(w);
s1 = x1*auxw;
s2 = x2*auxw; %// Change for correctness
%// Compute the vector projection
y1 = bsxfun(#times, s1, auxw.');
y2 = bsxfun(#times, s2, auxw.');
%// Place the original vectors and corresponding projections
%// in one matrix
y = [y1; y2];
x = [x1; x2];
%// Loop through and plot w, a point in either x1 or x2
%// and the corresponding projection
for ii = 1 : size(y,1)
plot([0 w(1)], [0 w(2)]);
hold on;
plot([0 y(ii,1)], [0 y(ii,2)], 'r');
plot([0 x(ii,1)], [0 x(ii,2)], 'g');
pause(0.5);
clf;
end
The function bsxfun allows us to multiply each vector in x1 and x2 by their corresponding scalar values. Specifically, it will take the vectors s1 and s2 and when we transpose auxw to be a 1 x 2 vector, we will create new matrices y1 and y2 where each row of either will compute the vector projections of x1 and x2 and place them into the rows of y1 and y2.
The loop at the end cycles through w, a vector in either x1 or x2 and the corresponding projected vector one at a time and we pause for 0.5 seconds each time to see what the results look like. The vector w is in blue, the projected vector is in green and the original vector from either x1 or x2 is in red.
We get these series of figures:
We can see that the red line, which is the projected vector from either x1 or x2 onto w. The green line is the original vector from either x1 or x2.

how to plot x,y,z in matlab?

I am making the Gauss-Jordan method in matlab and I want to plot these equations
x + y + 4*z = -1
-2*x – y + z= -5
3*x-2*y+3*z=-4
To see in what point of the graph they intersect, but I do not know how to plot in matlab
Is this what you are looking for?
clc
clear
close all
%// Generate x and y values to plot from.
[x,y] = meshgrid(linspace(0,10,100),linspace(0,10,100));
%// Get equation for plane; i.e. z position
z1 = 0.25.*(-1-x-y);
z2 = -5+y+2*x;
z3 = (-4-3.*x+2.*y)./3;
%// Use surf to generate surface plots
figure;
surf(x,y,z1,'linestyle','none','facealpha',0.4)
hold on
surf(x,y,z2,'linestyle','none','facealpha',0.4)
surf(x,y,z3,'linestyle','none','facealpha',0.4)
hold off
%// Use to manually rotate the plot
rotate3d on
Which gives this:
You can play around with the 'FaceAlpha' property of course to make things clearer. Have a look at the surf function for more options.
EDIT:
Alternatively to #rayryeng solution to solve for x,y and z you can use mldivide:
A = [1 1 4;-2 -1 1;3 -2 3];
B = [-1;-5;-4];
X = mldivide(A,B)
X =
1.0000
2.0000
-1.0000
Here is how i would plot those planes.
The 4-th argument of surf lets you specify the color.
% // create function handles of form z = f(x,y)
f1 = #(X,Y) 1/4*(-1 - X -Y);
f2 = #(X,Y) -5 + 2*X + Y;
f3 = #(X,Y) 1/3*(-4 -3*X + 2*Y);
% // create a 2d-grid to plot the functions over
x = linspace(-5, 5, 10);
y = linspace(-10, 10, 20);
[X,Y] = meshgrid(x,y);
% // plot the planes in different colors (4th argument) and without edges
figure
surf(X, Y, f1(X,Y), ones(size(f1(X,Y))), 'EdgeColor', 'None');
hold on
surf(X, Y, f2(X,Y), ones(size(f2(X,Y)))*2, 'EdgeColor', 'None');
surf(X, Y, f3(X,Y), ones(size(f3(X,Y)))*3, 'EdgeColor', 'None');
legend('plane1', 'plane2', 'plane3')
xlabel('x'), ylabel('y'), zlabel('z')
Though this is not plotting, perhaps this is also something you can use. If you want to determine the simultaneous solution to those equations, consider using solve
syms x y z
A = solve('x + y + 4*z == -1', '-2*x - y + z == -5', '3*x - 2*y + 3*z == -4')
disp([A.x A.y A.z]);
[ 1, 2, -1]
This will check to see whether your Gauss-Jordan elimination is correct. If you don't like using solve, you can use linear algebra to help you solve this for you. Simply place your coefficients for your system in a matrix and vector, then find the inverse of the matrix and multiply by the vector.
A = [1 1 4; -2 -1 1; 3 -2 3];
b = [-1;-5;-4];
x = A \ b
x =
1.0000
2.0000
-1.0000
... and even another method is to use rref to reduce your system into row-reduced echelon form. This would be the result after you successfully apply Gauss-Jordan elimination to your linear system. As such:
A = [1 1 4; -2 -1 1; 3 -2 3];
b = [-1;-5;-4];
rref([A b])
ans =
1 0 0 1
0 1 0 2
0 0 1 -1
Reading the above answer, x = 1, y = 2, z = -1. This represents the augmented system where the first 3 columns denote the coefficients of your system and the fourth column denotes the right hand side of your linear system of equations.