Matlab newb here. I have searched and haven't found how to do the following:
x=0.1:1/100:10;
y=exp(a(a>=-1&a<=1)*sqrt(x));
plot(x,y)
I realize that the dimensions of x and a don't match, but I just want to express: "what does y look like when a constant, a, is constrained between -1 and 1", for example.
Any hints are appreciated. Thanks in advance.
Assuming a and x are independent, you can go along these lines, using bsxfun to compute y for all combinations of a and x:
x = 0.1:1/100:10; %// define x values
a = linspace(-1,1,10); %// define a values
y = exp( bsxfun(#times, a, sqrt(x).') ); %'// compute y for all combinations
plot(x,y); %// this plots each column of y. Each colum represents a value of a
Or plot as a 3D graph (y as a function of a and x):
mesh(a,x,y)
xlabel('a')
ylabel('x')
zlabel('y')
You can do as follows:
x=0.1:1/100:10; % 991 clips
a=-1:1/495:1; % use 1/495 here to make it also 991 clips
y=exp(a.*sqrt(x));
plot(x,y)
This will give you the following figure:
Related
I'm very new to Matlab. I'm trying to plot X, where X is an 100x1 vector, against Y, which is an 100x10 matrix. I want the result to be X vs 10 different Y values all in the same graph, different colors for each column. The only way I can think of plotting each column of this matrix is by using the hold command, but then I have to split it up so I get each column individually. Is there an easy way to do this?
Use repmat to expand X to be the same size as Y. Try plotting them with plot(X,Y) and if it looks strange, transpose each one (plot(X',Y')).
You can use linespec arguments to select linestyle, marker style, etc. For example, plot(X,Y,'.') would indicate a point at each vertex with no connecting lines.
You don't need to use repmat, just use plot instead of scatter:
plot(X,Y,'o')
Here's an example:
% some arbitrary data:
X = linspace(-2*pi,2*pi,100).'; % size(X) = 100 1
Y = bsxfun(#plus,sin(X),rand(100,10)); % size(Y) = 100 10
% you only need the next line:
plot(X,Y,'o')
legend('show')
MATLAB's surf command allows you to pass it optional X and Y data that specify non-cartesian x-y components. (they essentially change the basis vectors). I desire to pass similar arguments to a function that will draw a line.
How do I plot a line using a non-cartesian coordinate system?
My apologies if my terminology is a little off. This still might technically be a cartesian space but it wouldn't be square in the sense that one unit in the x-direction is orthogonal to one unit in the y-direction. If you can correct my terminology, I would really appreciate it!
EDIT:
Below better demonstrates what I mean:
The commands:
datA=1:10;
datB=1:10;
X=cosd(8*datA)'*datB;
Y=datA'*log10(datB*3);
Z=ones(size(datA'))*cosd(datB);
XX=X./(1+Z);
YY=Y./(1+Z);
surf(XX,YY,eye(10)); view([0 0 1])
produces the following graph:
Here, the X and Y dimensions are not orthogonal nor equi-spaced. One unit in x could correspond to 5 cm in the x direction but the next one unit in x could correspond to 2 cm in the x direction + 1 cm in the y direction. I desire to replicate this functionality but drawing a line instead of a surf For instance, I'm looking for a function where:
straightLine=[(1:10)' (1:10)'];
my_line(XX,YY,straightLine(:,1),straightLine(:,2))
would produce a line that traced the red squares on the surf graph.
I'm still not certain of what your input data are about, and what you want to plot. However, from how you want to plot it, I can help.
When you call
surf(XX,YY,eye(10)); view([0 0 1]);
and want to get only the "red parts", i.e. the maxima of the function, you are essentially selecting a subset of the XX, YY matrices using the diagonal matrix as indicator. So you could select those points manually, and use plot to plot them as a line:
Xplot = diag(XX);
Yplot = diag(YY);
plot(Xplot,Yplot,'r.-');
The call to diag(XX) will take the diagonal elements of the matrix XX, which is exactly where you'll get the red patches when you use surf with the z data according to eye().
Result:
Also, if you're just trying to do what your example states, then there's no need to use matrices just to take out the diagonal eventually. Here's the same result, using elementwise operations on your input vectors:
datA = 1:10;
datB = 1:10;
X2 = cosd(8*datA).*datB;
Y2 = datA.*log10(datB*3);
Z2 = cosd(datB);
XX2 = X2./(1+Z2);
YY2 = Y2./(1+Z2);
plot(Xplot,Yplot,'rs-',XX2,YY2,'bo--','linewidth',2,'markersize',10);
legend('original','vector')
Result:
Matlab has many built-in function to assist you.
In 2D the easiest way to do this is polar that allows you to make a graph using theta and rho vectors:
theta = linspace(0,2*pi,100);
r = sin(2*theta);
figure(1)
polar(theta, r), grid on
So, you would get this.
There also is pol2cart function that would convert your data into x and y format:
[x,y] = pol2cart(theta,r);
figure(2)
plot(x, y), grid on
This would look slightly different
Then, if we extend this to 3D, you are only left with plot3. So, If you have data like:
theta = linspace(0,10*pi,500);
r = ones(size(theta));
z = linspace(-10,10,500);
you need to use pol2cart with 3 arguments to produce this:
[x,y,z] = pol2cart(theta,r,z);
figure(3)
plot3(x,y,z),grid on
Finally, if you have spherical data, you have sph2cart:
theta = linspace(0,2*pi,100);
phi = linspace(-pi/2,pi/2,100);
rho = sin(2*theta - phi);
[x,y,z] = sph2cart(theta, phi, rho);
figure(4)
plot3(x,y,z),grid on
view([-150 70])
That would look this way
I have this script:
scatter(X,Y)
p = polyfit(X,Y,1);
FX= polyval(p,X);
hold on
plot(X,FX)
which for the actual data XY gives me this chart:
In the chart you see the hidden line in blu that I traced manually on the picture. Normally I do this in excel adding an additional X point but obviously this does not work in Matlab. How can I obtain such extension in Matlab?
You can do the same thing: append a new value to X and regenerate FX using polyval
newX = [X; 140];
newFX = polyval(p, newX);
plot(newX, newFX);
this will work if X is a column vector. If it's a row vector then append horizontally using [X 140] instead.
Like in excell you need to add X points.
Here's an example:
scatter(X,Y);
p = polyfit(X,Y,1); %// estimating the line paramters
Now all you need is use different X values ( suppose maxX=140 ):
plotX = linspace( min(X), maxX, 100 );
FX= polyval(p,plotX);
plot( plotX, FX );
I want to plot relations like y^2=x^2(x+3) in MATLAB without using ezplot or doing algebra to find each branch of the function.
Does anyone know how I can do this? I usually create a linspace and then create a function over the linspace. For example
x=linspace(-pi,pi,1001);
f=sin(x);
plot(x,f)
Can I do something similar for the relation I have provided?
What you could do is use solve and allow MATLAB's symbolic solver to symbolically solve for an expression of y in terms of x. Once you do this, you can use subs to substitute values of x into the expression found from solve and plot all of these together. Bear in mind that you will need to cast the result of subs with double because you want the numerical result of the substitution. Not doing this will still leave the answer in MATLAB's symbolic format, and it is incompatible for use when you want to plot the final points on your graph.
Also, what you'll need to do is that given equations like what you have posted above, you may have to loop over each solution, substitute your values of x into each, then add them to the plot.
Something like the following. Here, you also have control over the domain as you have desired:
syms x y;
eqn = solve('y^2 == x^2*(x+3)', 'y'); %// Solve for y, as an expression of x
xval = linspace(-1, 1, 1000);
%// Spawn a blank figure and remember stuff as we throw it in
figure;
hold on;
%// For as many solutions as we have...
for idx = 1 : numel(eqn)
%// Substitute our values of x into each solution
yval = double(subs(eqn(idx), xval));
%// Plot the points
plot(xval, yval);
end
%// Add a grid
grid;
Take special care of how I used solve. I specified y because I want to solve for y, which will give me an expression in terms of x. x is our independent variable, and so this is important. I then specify a grid of x points from -1 to 1 - exactly 1000 points actually. I spawn a blank figure, then for as many solutions to the equation that we have, we determine the output y values for each solution we have given the x values that I made earlier. I then plot these on a graph of these points. Note that I used hold on to add more points with each invocation to plot. If I didn't do this, the figure would refresh itself and only remember the most recent call to plot. You want to put all of the points on here generated from all of the solution. For some neatness, I threw a grid in.
This is what I get:
Ok I was about to write my answer and I just saw that #rayryeng proposed a similar idea (Good job Ray!) but here it goes. The idea is also to use solve to get an expression for y, then convert the symbolic function to an anonymous function and then plot it. The code is general for any number of solutions you get from solve:
clear
clc
close all
syms x y
FunXY = y^2 == x^2*(x+3);
%//Use solve to solve for y.
Y = solve(FunXY,y);
%// Create anonymous functions, stored in a cell array.
NumSol = numel(Y); %// Number of solutions.
G = cell(1,NumSol);
for k = 1:NumSol
G{k} = matlabFunction(Y(k))
end
%// Plot the functions...
figure
hold on
for PlotCounter = 1:NumSol
fplot(G{PlotCounter},[-pi,pi])
end
hold off
The result is the following:
n = 1000;
[x y] = meshgrid(linspace(-3,3,n),linspace(-3,3,n));
z = nan(n,n);
z = (y .^ 2 <= x .^2 .* (x + 3) + .1);
z = z & (y .^ 2 >= x .^2 .* (x + 3) - .1);
contour(x,y,z)
It's probably not what you want, but I it's pretty cool!
I apologize for asking this, I believe this is a simple task, but I don't know how to do it.
Suppose I have a formula y = (exp(-x) + x^2)/sqrt(pi(x) and I want to plot it as y versus x^2.
How does one do this?
Like this:
X = 0:0.1:5; %// Get the x values
x = X.^2; %// Square them
%// Your formula had errors, I fixed them but I could have misinterpreted here, please check
y = (exp(-x) + x.^2)./sqrt(pi*x); %// Calculate y at intervals based on the squared x. This is still y = f(x), I'm just calculating it at the points at which I want to plot it.
plot(x,y) %//Plot against the square X.
At this point this is no different to having just plotted it normally. What you want is to make the tickmarks go up in values of X.^2. This does not change the y-values nor distort the function, it just changes what it looks like visually. Similar to plotting against a log scale:
set(gca, 'XTick', X.^2) %//Set the tickmarks to be squared
The second method gives you a plot like
edit:
Actually I think you were asking for this:
x = 0:0.1:5;
y = x.^2; %// Put your function in here, I'm using a simple quadratic for illustrative purposes.
plot(x.^2,y) %//Plot against the square X. Now your y values a f(x^2) which is wrong, but we'll fix that later
set(gca, 'XTick', (0:0.5:5).^2) %//Set the tickmarks to be a nonlinear intervals
set(gca, 'XTickLabel', 0:0.5:5) %//Cahnge the labels to be the original x values, now accroding to the plot y = f(x) again but has the shape of f(x^2)
So here I'm plotting a simple quadratic, but if I plot it against a squared x it should become linear. However I still want to read off the graph that y=x^2, not y=x, I just want it to look like y=x. So if I read the y value for the x value of 4 on that graph i will get 16 which is still the same correct original y value.
Here's my answer: it is similar to Dan's one, but fundamentally different. You can calculate the values of y as a function of x, but plot them as a function of x^2, which is what the OP was asking, if my understanding is correct:
x = 0:0.1:5; %// Get the x values
x_squared = x.^2; %// Square them
%// Your formula had errors, I fixed them but I could have misinterpreted here, please check
y = (exp(-x) + x.^2)./sqrt(pi*x); %// Calculate y based on x, not the square of x
plot(x_squared,y) %//Plot against the square of x
As Dan mentioned, you can always change the tickmarks:
x_ticks = (0:0.5:5).^2; % coarser vector to avoid excessive number of ticks
set(gca, 'XTick', x_ticks) %//Set the tickmarks to be squared