How to segment a curve into linear and nonlinear pieces
8 views (last 30 days)
Show older comments
I have a dataset which looks linear at the beginning (up to ~3.5 along x-axis) and then it shows and upward climb. I want to locate an ideal point uptill where the data is linear at the beginning and fit a line. Thanks a lot. The data is attached (1st column is X and 2nd column is Y).
2 Comments
Bruno Luong
on 19 Jul 2023
linear about 3.5 ? When I zoom in it is not clear where the linear starts. Not 3.5, not 2, may be on the interval (0,1)
Accepted Answer
Chunru
on 19 Jul 2023
load(websave("DatasetXY.mat", "https://www.mathworks.com/matlabcentral/answers/uploaded_files/1437433/DatasetXY.mat"));
whos
[~, ia] = unique(XY(:, 1)); % remove the duplicated points
XY = XY(ia, :);
plot(XY(:,1), XY(:,2));
gg = gradient(gradient(XY(:, 2), XY(:, 1)), XY(:, 1)); % 2nd derivative
gg = movmedian(gg, 20); % to remove some spikes
hold on;
whos
% ignore some initial points
ip = 20; % 20 points
gg((ip+1):end)
i = find(abs(gg((ip+1):end))>20, 1, 'first'); % 2000 as a threshod (adjust it)
i = ip+i
plot(XY(i,1), XY(i, 2), 'ro');
%xlim([2 3])
0 Comments
More Answers (1)
Bruno Luong
on 19 Jul 2023
Edited: Bruno Luong
on 19 Jul 2023
Ths produces kind of "arbitrary" choice of the breakpoint, consider fitting the global curve with few line segments
load(websave("DatasetXY.mat", "https://www.mathworks.com/matlabcentral/answers/uploaded_files/1437433/DatasetXY.mat"));
X=XY(:,1);
Y=XY(:,2);
% FEX https://uk.mathworks.com/matlabcentral/fileexchange/25872-free-knot-spline-approximation
% it takes a dozain of seconds here
pp = BSFK(X,Y,2,[],[],struct('Animation',true))
xbreaks=pp.breaks(2)
ybreaks=ppval(pp,xbreaks)
plot(xbreaks,ybreaks,'or','MarkerSize',15)
1 Comment
Bruno Luong
on 19 Jul 2023
If I crop the data up to X <= 4 it finds the break at
xbreaks=2.3085
As I said it's a mmoving target. The data is more or less exponetial everywhere. It is just a question of scaling, totally subjective.
load(websave("DatasetXY.mat", "https://www.mathworks.com/matlabcentral/answers/uploaded_files/1437433/DatasetXY.mat"));
X=XY(:,1);
Y=XY(:,2);
b = X < 4
% FEX https://uk.mathworks.com/matlabcentral/fileexchange/25872-free-knot-spline-approximation
% it takes a dozain of seconds here
pp = BSFK(X(b),Y(b),2,[],[],struct('Animation',true))
xbreaks=pp.breaks(2)
ybreaks=ppval(pp,xbreaks)
plot(xbreaks,ybreaks,'or','MarkerSize',15)
See Also
Categories
Find more on Biological and Health Sciences in Help Center and File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!