Query regarding finding the index which will give 90% of the total area under the curve

7 views (last 30 days)
I have a curve obtained using curve fitting toolbox.
I calculated the area of this curve using both 'trapz' and 'polyarea' function. I got this around 35704 square units. Now, I want to find the index on the X-axis till which my area is 90% of total area (i.e. 90% of 35704 square units). Is there any function for this?
If the question is not clear, feel free to comment.

Accepted Answer

Walter Roberson
Walter Roberson on 26 Nov 2020
Edited: Walter Roberson on 26 Nov 2020
A = cumtrapz(x, y);
x_idx = find(A >= 0.9 * A(end), 1);

More Answers (1)

John D'Errico
John D'Errico on 26 Nov 2020
No. You found some approximations of the area, using either trapz or polyarea. In both cases, they produced what is a trapezoidal rule approximation to the area, since they are implicitly piecewise linear tools. You do not give us any clue how that curve was "obtained" from the curve fitting toolbox, but since that toolbox does not provide data in any way, we are at a loss to know what you mean by that comment.
If you used trapz however, you can trivially use cumtrapz. I lack your data, so I cannot use it as an example. But, trivially if you find the location where
cumtrapz(x,y)/trapz(x,y)
is approximately 0.9, then you have found the 90% point on your curve. You can use interp1 to do that interpolation, either to find an interpolated point, or to find the index which is closest to 0.9 in area. You could also just use discretize to find the location, from the cumulative integral curve. Take your pick of the methods I have described. Depending on the curve itself, if you actually fit the curve with some model from the curve fitting toolbox, there are many other things you could hve done. But for that, you would need to be forthcoming with real information.
  2 Comments
NAVNEET NAYAN
NAVNEET NAYAN on 26 Nov 2020
Edited: NAVNEET NAYAN on 26 Nov 2020
%% Clearing workspace, command windows and other variables
tic;
clc;
clear all;
close all;
%% Laoding matrix containing amount of videos vs number of frames
t=load('amount of videos vs number of frames.mat'); %loading the matrix containing amount of videos vs number of frames
t1=t.numframe; % Extracting numframe field from the structure 't'
%% Removing zeros from the matrix t1 and finding unique elements from that
t1 = nonzeros(t1); % finding non-zeros elements in t1
t1 = reshape(t1,107,350); % reshaping t1
t2=unique(t1); % finding unique elements from t1
%% plotting the curve of amount of videos vs number of frames an finding area and using curve fitting
for k=1:length(t2)
number(k,1)=sum(t1(:)==t2(k)); %finding number of times every element of t2 is repeated
end
plot(t2,number); % plot of t2 vs number
figure;
[a,b,c]=fit(t2,number,'cubicinterp'); % curve fitting
plot(a) % plotting fitobject
area=cumtrapz(t2,number); % finding area of the curve
toc;
Though I have got the answer, I am just providing the details of my work through my code. In case you need some more details, please feel free to discuss.
John D'Errico
John D'Errico on 28 Nov 2020
You need to be careful if you are using a cubic interpolant of any form to plot a noisy function. Note the solution for the are that I showed (the same as what was shown by Walter) uses an implicitly PIECEWISE LINEAR interpolant. But then you plot the curve using a cubic interpolant. You want to be consistent.

Sign in to comment.

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!