X value for given y value [duplicate] - matlab

This question already has answers here:
Spline interpolation in matlab in order to predict value
(2 answers)
Extracting x value given y threshold from polyfit plot (Matlab)
(1 answer)
Closed 4 years ago.
i have a very simple question but i can't find my wrong. I have two signals, one same x axes and two signals value on y axis. I need to find the y value of green signal on the black line, so where y value of blue signal is 50.05. It should be between 6-7. I thought that i should first get same x value (4.676). Then get the y value of green signal where x is 4.676. So i need to get first 4.676 but i can't get this x value on given y value. I tried this but it comes always empty matrix.
xvalue = interp1(x_bluesignal,y_bluesignal, 50.05)
and
idx = find(x_bluesignal == 50.05);
Xidx = x_bluesignal(idx);
Any idea? Thank you!

As #obchardon pointed out in the comments, you want to interpolate on the x-value, not the y-value. As a simple example, consider the following:
%Plot two original lines
x = linspace(0,20,101);
y1 = 5*x+2;
y2 = 3*x+5;
plot(x, y1, 'b', x, y2 ,'g'); hold on
%Plot intersection line at desired y_interest value
y_interest = 50.05;
xvalue = interp1(y1, x, y_interest);
plot([xvalue, xvalue], [0, 100], 'k--')
x_interest = interp1(x, y2, xvalue);
This produces the following plot:
Once you've interpolated on x to find the correct x-value, you can then feed that value to your next interpolation on the y-values of the green curve. In the example above, this will output 33.8300.

In both your attempts you are actually asking MATLAB for the y value where x is 50.05, rather than your intended query.
Both
xvalue = interp1(y_bluesignal,x_bluesignal, 50.05)
and
idx = find(y_bluesignal == 50.05);
Xidx = x_bluesignal(idx);
may work if there is an entered data point at y=50.05 (use a tolerance as in the above comments if this is a calculated value), the interp method will work regardless

Related

How can I find a specific point in a figure in MATLAB?

I want a specific value in the figure in MATLAB. I put the black circle and arrow manually through the figure insert option. But How can I set the value now?
I want the x-axes values that are exactly 90% of each CDF curve.
here I am attaching my MatLab figure in jpg mode.
I would use interp1 to find the value. I'll assume that your x variable is called x and your cdf value is called c. You can then use code like this to get the x value where c = 0.9. This will work even if you don't have a cdf value at exactly 0.9
x_at_0p9 = interp1(c, x, 0.9);
You plotted those figures by using:
plot(X,Y)
So, your problem is to find x_0 value that makes Y = 0.9.
You can do this:
ii = (Y==0.9) % finding index
x_0 = X(ii) % using index to get x_0 value
Of course this will only work if your Y vector has exactly the 0.9 value.
As this is not always the case you may want to get the x_0 value that first makes Y to be greater or equal than 0.9.
Then you can do this:
ii = find(Y>=0.9, 1) % finding index
x_0 = X(ii) % using index to get x_0 value
Assuming that your values are x and Y (where x is a vector and the same for all curves) and Y is a matrix with the same number of rows and as many columns as there are curves; you just need to find the first point where Y exceeds 0.9:
x = (0:0.01:pi/2)'; % time vector
Y = sin(x*rand(1,3))*10; % value matrix
% where does the values exceed 90%?
lg = Y>= 0.9;
% allocate memory
XY = NaN(2,size(Y,2));
for i = 1:size(Y,2)
% find first entry of a column, which is 1 | this is an index
idx = find(lg(:,i),1);
XY(:,i) = [x(idx);Y(idx,i)];
end
plot(x,Y, XY(1,:),XY(2,:), 'o')

Area between line and curve (no function)

I want to calculate the area beween the orange and the blue line. I managed to shade the area. But I do not know how to apply the trapz function in order to get the area. In this post: Area under surface between two curves I got some solutions but I do not have a specific equation for the curves just the plots per se.
The code for the orange line is:
x_1 = [0,M1_1];
y_1 = [c1,c1];
v = plot(x_1,y_1,'LineWidth',2)
The blue curve is a plot of arrays with the length of (10000x1)-abscissa and (1x10000)-ordinate.
If I use
%c0_1: Intersection blue curve with y-axis
%c1_1: Intersection orange curve with y-axis
A = trapz(ab1(0:c1_1),ab_y1(c1_1:c0_1))
I get the following error:
Warning: Integer operands are required for colon operator when used as
index Warning: Integer operands are required for colon operator when
used as index Error using trapz (line 58) LENGTH(X) must equal the
length of Y in dim 2.
How can I apply my trapz function easily on my problem?
Here is an answer, although I'm not sure what is the difference between the situation here and here, and therefore I'm not sure it truelly answers your question...
Anyway, you don't need to know y1 function explicitly, just to have its' series of data.
x = 0:0.1:12; % x data
y1 = 3*exp(-0.5*x); % y data
y2 = 0.5;
lineStart = find(x>=0,1);
lineEnd = find(y1<=y2,1);
f = plot(x,y1,'b',x,ones(1,length(x))*y2,'r','LineWidth',2);
ylim([0 4])
hold on
area(x(lineStart:lineEnd),y1(lineStart:lineEnd), y2,...
'EdgeColor', 'none', 'FaceColor', [0.5 0.5 1],'ShowBaseLine','off')
hold off
A = trapz(x(lineStart:lineEnd),y1(lineStart:lineEnd));
I added also the illustration of the integrated area:
Tell me is that solves the problem ;)

Matlab partial area under the curve

I want to plot the area above and below a particular value in x axis.
The problem i am facing is with discrete values. The code below for instance has an explicit X=10 so i have written it in such a way that i can find the index and calculate the values above and below that particular value but if i want to find the area under the curve above and below 4 this program will now work.
Though in the plot matlab does a spline fitting(or some sort of fitting for connecting discrete values) there is a value for y corresponding to x=4 that matlab computes i cant seem to store or access it.
%Example for Area under the curve and partial area under the curve using Trapezoidal rule of integration
clc;
close all;
clear all;
x=[0,5,10,15,20];% domain
y=[0,25,50,25,0];% Values
LP=log2(y);
plot(x,y);
full = trapz(x,y);% plot of the total area
I=find(x==10);% in our case will be the distance value up to which we want
half = trapz(x(1:I),y(1:I));%Plot of the partial area
How can we find the area under the curve for a value of ie x = 2 or 3 or 4 or 6 or 7 or ...
This is an elaboration of patrik's comment, "first interpolate and then integrate".
For the purpose of this answer I'll assume that the area in question is the area that can be seen in the plot, and since plot connects points by straight lines I assume that linear interpolation is adequate. Moreover, since the trapezoidal rule itself is based on linear interpolation, we only need interpolated values at the beginning and end of the interval.
Starting from the given points
x = [0, 5, 10, 15, 20];
y = [0, 25, 50, 25, 0];
and the integration interval limits, say
xa = 4;
xb = 20;
we first select the data points within the limits
ind = (x > xa) & (x < xb);
xw = x(ind);
yw = y(ind);
and then complete them by interpolation values at the edges:
ya = interp1(x, y, xa);
yb = interp1(x, y, xb);
xw = [xa, xw, xb];
yw = [ya, yw, yb];
Now we can simply apply trapezoidal integration:
area = trapz(xw, yw);
I think that you either need more samples, or to interpolate the data. Another alternative is to use a function handle. Then you need to know the function though. Example using linear interpolation follows.
x0 = [0;5;10;15;20];
y0 = [0,25,50,25,0];
x1 = 0:20;
y1 = interp1(x0,y0,x1,'linear');
xMax = 4;
partInt = trapz(x1(x1<=xMax),y1(x1<=xMax));
Some other kind of interpolation may be suitable, but that is hard to say without more information. Also, this interpolates from the beginning to x. However, I guess figuring out how to change the limits should be easy from here. This solution is different than the former, since it is less depending on the pyramid shape of the data. So to say, it is more general.

How to plot graph with customized axis

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

MATLAB: How do I graph multiple functions on the same graph?

How can I graph multiple functions on the same graph/plot/Cartesian plane on MATLAB with domain and range restrictions?
For example I made up the following functions below. How would I graph the following on the same graph within MATLAB?
Function 1: x = -3 for 10 <= y <= 14
Function 2: y = -2x for -5 <= x <= -4
Function 3: (x-0)^2 + (y-12)^2 = 2.25 // Produces a circle
Function 4: y = 4 for -1 <= x <= 1
Matlab is a numerical computing environment, so you'll need to tell it what you're looking for while plotting.
In the case of your first example, you'll need to tell it which Y values to plot. Since X is always the same, you know it's going to be a line - so two points will be enough. Plot requires parallel arrays, so:
Function 1: x = [-3 -3]; y = [10 14]; plot(x, y);
To plot additional lines on the same graph, use the command hold on, which applies to the figure you just plotted. If you don't do this, new plot commands will erase the old plots.
Similarly,
Function 2: x = [-5 4]; y = -2*x; plot(x, y);
For circles/ellipses like #3, ezplot can be helpful, although you still have to specify the range.
Function 3: ezplot('x^2 + (y-12)^2 - 2.25', [-3,3,10,14])
The last one is easy, but let's say it were a curve instead. You'd want to plot more than just two x values. You can create a vector from a range like this: x = -1:0.1:1;, or an evenly space set of points from -1 to 1, with an interval of 0.1. Let's say you want to plot it on the same graph, and you've already done hold on. You want a different color, and you want to show the individual points that make up the line, you can use the third argument to the plot function:
Function 4: x = -1:0.1:1; y = 4 * ones(length(x)); plot(x, y, '-r.');
The second command here, y = 4 * ones(length(x)); simply creates a y vector that is the same length as x.