MATLAB Answers

Hello everyone, how to divide a piece of data into upper and lower parts along the y-axis with C point and D point as the boundary?

29 views (last 30 days)
Wesley
Wesley on 19 Jan 2021
Commented: Star Strider on 20 Jan 2021

  1 Comment

Wesley
Wesley on 19 Jan 2021
Points C and D have been calculated.
load data1.mat
x = data1(:, 1);
y = data1(:, 2);
%Calculate points C and D
[a,I]=min(x);
C=[a,y(I)];
[b,J]=max(x);
D=[b,y(J)];
hold on

Sign in to comment.

Accepted Answer

Star Strider
Star Strider on 19 Jan 2021
Try this:
D = load('data1.mat');
data1 = D.data1;
x = data1(:, 1);
y = data1(:, 2);
[C,ixmin] = min(x);
[D,ixmax] = max(x);
B = [x(ixmin) 1; x(ixmax) 1] \ [y(ixmin); y(ixmax)];
[xsort,sortidx] = sort(x);
fitline = [xsort ones(size(xsort))] * B;
topidx = y(sortidx) >= fitline;
figure
plot(x(sortidx(topidx)), y(sortidx(topidx)), '.r')
hold on
plot(x(sortidx(~topidx)), y(sortidx(~topidx)), '.g')
plot(xsort, fitline, '-b')
plot(C,y(ixmin), 'bo', 'MarkerFaceColor','b')
plot(D,y(ixmax), 'bo', 'MarkerFaceColor','b')
hold off
xlabel('X')
ylabel('Y')
legend('Above Line', 'Below Line', 'Line', 'Location','SE')
text(C,y(ixmin), 'C ', 'HorizontalAlignment','right', 'VerticalAlignment','middle')
text(D,y(ixmax), ' D', 'HorizontalAlignment','left', 'VerticalAlignment','middle')
producing:
.

  9 Comments

Show 6 older comments
Star Strider
Star Strider on 19 Jan 2021
Success!
This took several hours to solve, and I wasn’t initially confident of the outcome.
This code works on this data set, however I seriously doubt that it is sufficiently robust to work on even similar data sets.
The Code —
D = load('data1.mat');
data1 = D.data1;
x = data1(:, 1);
y = data1(:, 2);
[data1_sorted,sortidx] = sortrows(data1,2);
xsort = data1_sorted(:,1);
ysort = data1_sorted(:,2);
[C,ixmin] = min(xsort);
[D,ixmax] = max(xsort);
ymin_idx = find(ysort == min(ysort)); % Minimum ‘y’ (Defines Approximate Minima Of Both Parts)
x_ymin = xsort(ymin_idx); % Corresponding ‘x’ Values
x_yminidx = find(ismember(xsort, x_ymin)); % Indices Of Both Parts Corresponding To Minimum ‘x’ Values
[maxymin,maxyminidx] = max(ysort(x_yminidx)); % Maximum O?f Corresponding ‘y’ Values (Defines Upper Part ‘y’ Values)
searchidxrange = x_yminidx(maxyminidx)+(-70:70); % Search Range For Minimum Upper Part ‘y’ Values
[min_uprcurv,minucidx] = min(ysort(searchidxrange)); % Minimum Upper Part ‘y’ Value & Index
min_uprcurvidx = searchidxrange(minucidx); % Index Of Search Range Corresponding To Minimum
idx4curv = ((xsort >= C) & (xsort <= D)) & (ysort >= ysort(min_uprcurvidx)); % Indices Of Upper Part Values
curlimidx = find(ysort == ysort(min_uprcurvidx)); % ‘y’ Values Corresponding To Minimum Of Upper Curve Indices
idxleft = (xsort >= C) & (xsort <= xsort(curlimidx(1))) & (ysort < ysort(ixmin)) & (ysort > ysort(min_uprcurvidx)); % ‘Tail’ Part Of Left Side To Be Excluded
idxright = (xsort <= D) & (xsort >= xsort(curlimidx(end))) & (ysort < ysort(ixmax)) & (ysort > ysort(min_uprcurvidx)); % ‘Tail’ Part Of Left Side To Be Excluded
idx4curv = idx4curv & ~(idxleft | idxright); % Upper Part Indices
idx4curvf = find(idx4curv); % Corresponding Numeric Indices
UpperPart = [xsort(idx4curv) ysort(idx4curv)]; % Upper Part ‘x’ & ‘y’ Values
LowerPart = [xsort(~idx4curv) ysort(~idx4curv)]; % Lower Part ‘x’ & ‘y’ Values
figure
scatter(UpperPart(:,1), UpperPart(:,2), '.r')
hold on
scatter(LowerPart(:,1), LowerPart(:,2), '.g')
plot(C,ysort(ixmin), 'bo', 'MarkerFaceColor','b')
plot(D,ysort(ixmax), 'bo', 'MarkerFaceColor','b')
hold off
axis('equal')
text(C,ysort(ixmin), 'C ', 'HorizontalAlignment','right', 'VerticalAlignment','middle')
text(D,ysort(ixmax), ' D', 'HorizontalAlignment','left', 'VerticalAlignment','middle')
legend('Upper Part', 'Lower Part', 'Location','SE')
The Plot —
.

Sign in to comment.

More Answers (1)

KSSV
KSSV on 19 Jan 2021
Edited: KSSV on 19 Jan 2021
Option 1: You should get the indices of C, D in the given points of curve. Read about knnsearch, this will give indices of points in curve which are close/ same as C and D. Once you know these indices, you can get the upper and lower curve depending on whether the points are in clockwise direction or anti clockwise direction.
Option 2: This is simple, you know C, D; as they lie on x-axes/ parallel to x-axes, these points should have same y. So:
idx1 = P(:,2)>=C(2) ; % C(2), D(2) both will be same
dataA = P(idx1,:) ;
dataB = P(~idx1,:) ;

Community Treasure Hunt

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

Start Hunting!