2 views (last 30 days)

Show older comments

I have plots like the one attached. At Y >0, the curve plateaus (flattens) before it increases sharply. I need to find the Y value at which the plateau/flat area is flattest.

Does anyone know how to do this? I can't figure out a solution that gets the part of the curve that I want. Thank you.

Star Strider
on 22 Aug 2021

T1 = readtable('https://www.mathworks.com/matlabcentral/answers/uploaded_files/718334/exampleData.txt')

T1 = rmmissing(T1); % Remove 'NaN' Values

h = mean(diff(T1.Var1))

d2d1 = gradient(T1.Var2, h); % Numerical Derivative

flatidx = find(abs(d2d1)<1E-14); % Zero Slope (With Tolerance)

yflat = T1.Var2(flatidx)

figure

plot(T1.Var1, T1.Var2)

hold on

plot(T1.Var1(flatidx), T1.Var2(flatidx), 'vr')

hold off

grid

legend('Data','Flat Section', 'Location','best')

This should also work with other data sets, although obviously I cannot test it with them.

.

Star Strider
on 23 Aug 2021

Set the conditions in the find call to match what you want to define.

T1 = readtable('https://www.mathworks.com/matlabcentral/answers/uploaded_files/718334/exampleData.txt')

T1 = rmmissing(T1); % Remove 'NaN' Values

h = mean(diff(T1.Var1))

d2d1 = gradient(T1.Var2, h); % Numerical Derivative

flatidx = find((abs(d2d1)<1.0) & (T1.Var2 > 0)); % Define Slope Criteria (With Tolerance)

yflat = T1.Var2(flatidx)

figure

plot(T1.Var1, T1.Var2)

hold on

plot(T1.Var1, d2d1)

plot(T1.Var1(flatidx), T1.Var2(flatidx), '.r')

hold off

grid

legend('Data', 'Numeircal Derivative', 'Flat Section', 'Location','best')

Make appropriate changes to get the result you want.

.

Turlough Hughes
on 23 Aug 2021

Edited: Turlough Hughes
on 23 Aug 2021

How robust this is depends on the consistency of that initial pattern, i.e. the initial acceleration followed by a period of deceleration (starting to plateau) until the "flattest" point where it then begins to accelerate again. This point between the initial deceleration and acceleration is also known as an inflection point, as mentioned by @dpb. It's also the point where where y is closest to being parallel to the x-axis in the region (where it is initially plateauing).

To find the inflection point we find the location where . I understand you want the second one as follows:

T = readmatrix('https://www.mathworks.com/matlabcentral/answers/uploaded_files/718334/exampleData.txt');

x = T(:,1);

y = T(:,2);

subplot(2,1,1)

plot(x,y,'LineWidth',3)

ylabel('f(x)'), xlabel('x')

set(gca,'fontSize',12)

subplot(2,1,2)

ypp = gradient(gradient(y,x),x); % second derivative of y w.r.t. x

plot(x,ypp,'LineWidth',3);

ylabel('f''''(x)')

xlabel('x')

set(gca,'fontSize',12)

idx = ypp > 0;

hold on, plot(x(idx),ypp(idx),'or','LineWidth',2)

iFlat = find(diff(idx)==1)+1; % y is most linear when it's second derivate, ypp, is equal to 0

iInflect = iFlat(2); % the second time ypp becomes > 0 approximates the second inflection point.

plot(x(iInflect),ypp(iInflect),'sk','MarkerSize',10,'LineWidth',2)

subplot(2,1,1)

hold on, plot(x(iInflect),y(iInflect),'sk','MarkerSize',10,'LineWidth',2)

x(1:iInflect-1) = [];

y(1:iInflect-1) = [];

plot(x,y,'--r','LineWidth',2)

legend('Original Dataset','Second Inflection Point','New Dataset','Location','NorthWest')

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

Start Hunting!