Lets say I have a sine curve and a cosine curve. Is there any way to add them graphically? Rather than doing sin + cos?
I'm plotting things that are functions of different variables (lets say one curve takes x-values from an array of integers and the other from an array of irrational numbers), so I don't know how else to add them.
Let's say you want to plot y1 = f1(x1) and y2 = f2(x2) you could do this
X = union(x1, x2);
Y1 = interp1(x1, y1, X);
Y2 = interp1(x2, y2, X);
Y = Y1 + Y2;
plot(X, Y)
So to see this in action
x1 = 2 * pi * rand(50, 1);
x2 = 2 * pi * rand(50, 1);
y1 = cos(x1).^2;
y2 = sin(x2).^2;
X = union(x1, x2);
Y1 = interp1(x1, y1, X);
Y2 = interp1(x2, y2, X);
Y = Y1 + Y2;
plot(X, Y)
Related
I would like to plot the following function:
I tried this code:
x = 0:0-1:4;
x1 = x(x<=-1);
x2 = x(x>-1 & x<=2);
x3 = x(x>2);
y1 = -3;
y2 = 1;
y3 = 4;
plot([x1 x2 x3], [y1 y2 y3])
But it is giving me the error that vectors must be the same length. How do I fix this error?
The problem is that matlab do not understand that y1=-3 means -3 for each value of x1. It needs a vector of -3s with as many elements as x1.
One way to define such a vector is the following:
x = -4:0.1:4;
x1 = x(x<=-1);
y1 = -3*ones(1,numel(x1));
So that you can plot the you want in the following way (look at it after giving it a try):
figure;hold on
x = -4:0.1:4;
x1 = x(x<=-1);
y1 = -3*ones(1,numel(x1));
plot(x1,y1)
x2 = x(x>-1 & x<=2);
y2 = ones(1,numel(x2));
plot(x2,y2)
x3 = x(x>2);
y3 = 4*ones(1,numel(x3));
plot(x3,y3)
x1 = 0:1:10;
x2 = 0.5:1:10;
X = [x1, x2];
Y = [(1/1.4).^x1, (2).^(-x2)];
stem(X,Y, 'filled', 'r')
What i want to do is to have the two series with different color.
How can i achieve that??
Try this :
x1 = linspace(0,10,11)';
x2 = linspace(0.5,10,11)';
X = [x1, x2];
Y = [(1/1.4).^x1, (2).^(-x2)];
h=stem(X,Y, 'filled');
set(h(1),'Color','r')
set(h(2),'Color','k')
I am trying to rotate the derivative of a gaussian (or the original guassian for that matter) by applying a rotation matrix to the X,Y coordinates and then plotting it as a mesh in matlab, but I'm running into an issue that the plot will only rotate by 90 degress each time and for all n*pi points there is no mesh appearing at all. I am wondering what I am doing wrong, hopefully someone can spot my error. I'm fairly new to matlab so forgive me if the code is not pretty. Thank you!
This is the code that I have:
sigma = 4;
[x,y] = deal(-3*sigma:.5:3*sigma);
[X,Y] = meshgrid(x,y);
B = [transpose(x) transpose(y)];
for i=1:1:16
figure(i);
theta = i*pi/8;
rotation = [cos(theta) sin(theta); -sin(theta) cos(theta)];
A = B * rotation;
[x_new, y_new] = meshgrid(A(:,1)', A(:,2)');
mesh(x_new, y_new, dgauss_x(x_new, y_new, sigma));
end
function f = dgauss_x(x, y, sigma)
%first order derivative of Gaussian
f = -x .* gaussian(x, y, sigma) ./ sigma^2;
function f = gaussian(x, y, sigma)
f = exp(-(x .^ 2 + y .^ 2)/(2*sigma^2)) / (sqrt(2*pi*(sigma^2)));
I figure it out. It was a dumb error. Basically I had to create a meshgrid for X and Y, reshape it into an Nx2 matrix of X and Y. Apply the rotation matrix, then reshape back and apply the Gaussian.
The code looks as follows (could be cleaned up):
for i=1:1:16
figure(i);
theta = i*pi/8;
rotation = [cos(theta) -sin(theta); sin(theta) cos(theta)];
X1 = reshape(X, length(x)*length(x), 1);
Y1 = reshape(Y, length(y)*length(y), 1);
B2 = [X1 Y1];
A = B2 * rotation;
X1 = A(:,1);
X1 = reshape(X1, length(x), length(x));
Y1 = A(:,2);
Y1 = reshape(Y1, length(y), length(y));
mesh(X1, Y1, dgauss_x(X1, Y1, sigma));
end
If I have two plots defined by two different equations:
x = 0:0.01:30;
y1 = x .^2 + 2;
y2 = x .^3 ;
and I plot them as
plot(x, y1, x, y2);
How do I get a small ring around the point of intersection programatically (as in the following plot)?
You'll have to find the point of intersection (px, py) manually:
idx = find(y1 - y2 < eps, 1); %// Index of coordinate in array
px = x(idx);
py = y1(idx);
Remember that we're comparing two numbers in floating point representation, so instead of y1 == y2 we must set a tolerance. I've chosen it as eps, but it's up to you to decide.
To draw a circle around this point, you can compute its points and then plot them, but a better approach would be to plot one point with a blown-up circle marker (credit to Jonas for this suggestion):
plot(px, py, 'ro', 'MarkerSize', 18)
This way the dimensions of the circle are not affected by the axes and the aspect ratio of the plot.
Example
x = 0:0.01:30;
y1 = x .^ 2 + 2;
y2 = x .^ 3;
%// Find point of intersection
idx = find(y1 - y2 < eps, 1);
px = x(idx);
py = y1(idx);
figure
plot(x, y1, x, y2, px, py, 'ro', 'MarkerSize', 18)
axis([0 10 0 10])
This should produce the following plot:
In your example, when you have x, y1 and y2
What you can do is
idx = find(abs(y1 - y2) == min(abs(y1 - y2)));
xInter = x(idx)
yInter = y1(idx) % or y2(idx)
If you have x1, y1 and x2, y2, where x1 ~= x2
you could first do 1D interpolation using
yy2 = interp1(x2, y2, x1);
then apply
idx = find(abs(y1 - yy2) == min(abs(y1 - yy2)));
xInter = x1(idx)
yInter = y1(idx) % or yy2(idx)
Excellent post by #EitanT, however I would like to complement this with a different (automated) way to find the intersection (Assuming there is one and the graphs behave nicely).
Here is our starting point:
x = 0:0.01:30;
y1 = x .^2 + 2;
y2 = x .^3 ;
First of all we check whether these values are exactly equal, for non-floating point non-discrete situations this should be sufficient:
idx = find(y1==y2)
If they are never recorded to be exactly equal, an intersection occurs if one surpasses the other, hence we look at the difference:
if isempty(idx)
d = y1-y2;
% At the moment of crossing, the sign will change:
s = diff(sign(d));
% Now just find the point where it changes
f = find(s,1);
end
To summarize this in compact form without additional variables, I would recommend using:
idx = find(y1==y2)
if isempty(idx)
idx = find(diff(sign(y1-y2)),1)
end
Especially when knowing the functions, the symbolic math toolbox can be used.
y1 = x .^2 + 2;
y2 = x .^3 ;
syms x real
intersection=simplify(solve(y1==y2))
Use vpa(intersection) to convert it to a number or double(intersection) to convert it to a floating point value.
Last but not least, perhaps the cleanest way to do this is the command polyxpoly:
[xi,yi] = polyxpoly(x,y1,x,y2)
xi = 1.69560153754948
yi = 4.87508921229275
Good luck!
How would you replace the following by meshgrid?
N=.33;
P=.45;
for i =1:10
for j=1:20
x0=i+N;
y0=j+P;
f(i,j)=exp(x0+y0);
end
end
I think something like
[X, Y] = meshgrid(1:10, 1:20);
Z = exp( (X+N) + (Y+P) );
% surf(X, Y, Z);
read here
edit
as user requested (if I've understood well):
[X, Y] = meshgrid(1:10, 1:20);
X1 = X + N; Y1 = Y + P;
Z = exp( X1 + Y1 );
% surf(X1, Y1, Z);