4 views (last 30 days)

Image Analyst
on 7 Mar 2020

Sorry for the delay. I'm sure you definitely figured it out by now, but for what it's worth, here it is for the first data set:

% Initialization steps:

clc; % Clear the command window.

close all; % Close all figures (except those of imtool.)

clearvars;

workspace; % Make sure the workspace panel is showing.

format long g;

format compact;

fontSize = 16;

markerSize = 15;

% Read in data from Excel workbook.

[numbers, strings, raw] = xlsread('combined_data.xlsx')

% Get first data set. Eliminate nan values.

x = numbers(:, 1);

x(isnan(x)) = [];

y = numbers(:, 2);

y(isnan(y)) = [];

numPoints = length(x)

hFig = figure;

subplot(2, 2, 1);

plot(x, y, 'b-', 'LineWidth', 2);

grid on;

xlabel('x', 'FontSize', fontSize);

ylabel('y', 'FontSize', fontSize);

title('Original Data', 'FontSize', fontSize);

hFig.WindowState = 'maximized'; % Maximize window.

% Assume the crossing point will be somewhere in the middle 80% of the points.

% Fit a line through the right and left parts and get the slopes.

% Keep the point where the slope difference is greatest.

index1 = round(0.1 * numPoints); % 10% of the way through.

index2 = round(0.9 * numPoints); % 90% of the way through.

% In other words, assume that we need at least 10 percent of the points to make a good estimate of the line.

% Obviously if we took only 2 or 3 points, then the slope could vary quite dramatically,

% so let's use at least 10% of the points to make sure we don't get crazy slopes.

% Initialize structure array

for k = 1 : numPoints

lineData(k).slopeDifferences = 0;

lineData(k).line1 = [0,0];

lineData(k).line2 = [0,0];

end

for k = index1 : index2

% Get data in left side.

x1 = x(1:k);

y1 = y(1:k);

% Fit a line through the left side.

coefficients1 = polyfit(x1, y1, 1); % The slope is coefficients1(1).

% Get data in right side.

x2 = x(k+1:end);

y2 = y(k+1:end);

% Fit a line through the left side.

coefficients2 = polyfit(x2, y2, 1); % The slope is coefficients2(1).

% Compute difference in slopes, and store in structure array along with line equation coefficients.

lineData(k).slopeDifferences = abs(coefficients1(1) - coefficients2(1));

lineData(k).line1 = coefficients1;

lineData(k).line2 = coefficients2;

end

% Find index for which slope difference is greatest.

slopeDifferences = [lineData.slopeDifferences]; % Extract from structure array into double vector of slope differences only

% slope1s = struct2table(lineData.line1); % Extract from structure array into double vector of slopes only

% slope2s = [lineData.line2(1)]; % Extract from structure array into double vector of slopes only

[maxSlopeDiff, indexOfMaxSlopeDiff] = max(slopeDifferences)

% Plot slope differences.

subplot(2, 2, 2);

plot(slopeDifferences, 'b.', 'MarkerSize', markerSize);

xlabel('Index', 'FontSize', fontSize);

ylabel('Slope Difference', 'FontSize', fontSize);

grid on;

caption = sprintf('Slope Differences Maximum at Index = %d, x value = %.2f', indexOfMaxSlopeDiff, x(indexOfMaxSlopeDiff));

title(caption, 'FontSize', fontSize);

% Mark it with a red line.

line([indexOfMaxSlopeDiff, indexOfMaxSlopeDiff], [0, maxSlopeDiff], 'Color', 'r', 'LineWidth', 2);

% Show everything together all on one plot.

% Plot lines.

subplot(2, 2, 3:4);

plot(x, y, 'b.', 'MarkerSize', markerSize);

grid on;

xlabel('x', 'FontSize', fontSize);

ylabel('y', 'FontSize', fontSize);

hold on;

% Use the equation of line1 to get fitted/regressed y1 values.

slope1 = lineData(indexOfMaxSlopeDiff).line1(1);

intercept1 = lineData(indexOfMaxSlopeDiff).line1(2);

y1Fitted = slope1 * x + intercept1;

% Plot line 1 over/through data.

plot(x, y1Fitted, 'r-', 'LineWidth', 2);

% Use the equation of line2 to get fitted/regressed y2 values.

slope2 = lineData(indexOfMaxSlopeDiff).line2(1);

intercept2 = lineData(indexOfMaxSlopeDiff).line2(2);

y2Fitted = slope2 * x + intercept2;

% Plot line 2 over/through data.

plot(x, y2Fitted, 'r-', 'LineWidth', 2);

% Mark crossing with a magenta line.

xc = (intercept2 - intercept1) / (slope1 - slope2);

xline(xc, 'Color', 'm', 'LineWidth', 2);

title('Data with left and right lines overlaid', 'FontSize', fontSize);

message1 = sprintf('Left Equation: y = %.3f * x + %.3f', slope1, intercept1);

message2 = sprintf('Right Equation: y = %.3f * x + %.3f', slope2, intercept2);

message = sprintf('%s\n%s', message1, message2);

fprintf('%s\n', message);

text(27, 7, message, 'Color', 'r', 'FontSize', 15, 'FontWeight', 'bold');

uiwait(helpdlg(message));

You'll notice that I picked a splitting point at every index from 10% of the way through until 90% of the way through and computed lines on each side of that split point. Then I looked at, and plotted in the upper left graph, the difference in slopes between the right line and left line. The best intersection point will be where the difference in slopes is greatest. You'll see this printed out:

maxSlopeDiff =

0.292467879717763

indexOfMaxSlopeDiff =

167

Left Equation: y = 0.003 * x + 4.042

Right Equation: y = 0.295 * x + -5.968

so you can see that at index 167, which is x=34.3, is the best place to split the curve up into two linear segments, and the equation of the lines on each side are given.

Did this match what you got for the two line equations? It should. Then you repeated it for the other two data sets, right? How did that work out?

Star Strider
on 7 Mar 2020

And of course —

T1 = readtable('combined_data.xlsx');

A = str2double(table2array(T1(2:end,:)));

figure

Cm = lines(fix(size(A,2)/2));

hold on

for k = 1:fix(size(A,2)/2)

x = A(:,1+2*(k-1));

y = A(:,2+2*(k-1));

cp{k} = ischange(y, 'linear', 'Threshold',0.25); % Find Change Points

cpidx{k} = find(cp{k}, 2, 'first'); % Change Point Indices

hl{k} = plot(x, y, ':', 'Color',Cm(k,:)); % Plot Raw Data

C = hl{k}.Color;

idxrng = {1:cpidx{k}(1); cpidx{k}(1):cpidx{k}(2)}; % Index Range For This Data Set

xr1 = x(idxrng{1}); % Data For Linear Regression

yr1 = y(idxrng{1}); % Data For Linear Regression

xr2 = x(idxrng{2}); % Data For Linear Regression

yr2 = y(idxrng{2}); % Data For Linear Regression

B{k,1} = [xr1(:) ones(size(xr1(:)))] \ yr1(:); % Estimate Parameters: First Set

B{k,2} = [xr2(:) ones(size(xr2(:)))] \ yr2(:); % Estimate Parameters: Second Set

% plot(x(cpidx{k}), y(cpidx{k}), '^', 'MarkerFaceColor',C, 'MarkerSize',10) % Plot Change Points (Un-Comment This Line To See Them)

yf1 = [xr1(:) ones(size(xr1(:)))] * B{k,1}; % Fit First Regression Line

yf2 = [xr2(:) ones(size(xr2(:)))] * B{k,2}; % Fit Second Regression Line

plot(xr1, yf1, 'Color',C, 'LineWidth',2) % Plot First Regression Line

plot(xr2, yf2, 'Color',C, 'LineWidth',2) % Plot Second Regression Line

xint(k,:) = (B{k,1}(2)-B{k,2}(2)) / (B{k,2}(1)-B{k,1}(1)); % Solve For ‘x’ Intersection

yint(k,:) = [xint(k) 1] * B{k,1}; % Solve For ‘y’ Intersection

% pause(5)

end

hold off

grid

legend([hl{:}], {'Columns 1:2','Columns 3:4','Columns 5:6'}, 'Location','E')

Regressions = array2table([B{:,1};B{:,2}], 'VariableNames',{'Cols_12','Cols_34','Cols_56'}, 'RowNames',{'Slope_1','Intercept_1','Slope_2','Intercept_2'})

Intersections = table(xint, yint, 'VariableNames',{'X_Intersect','Y_Intersect'}, 'RowNames',{'Cols_12','Cols_34','Cols_56'})

producing:

Regressions =

Cols_12 Cols_34 Cols_56

_________ _________ ________

Slope_1 0.0027788 0.0022421 0.003146

Intercept_1 4.0321 4.0616 4.0364

Slope_2 0.32669 0.30598 0.64086

Intercept_2 -6.9594 -7.1488 -19.264

Intersections =

X_Intersect Y_Intersect

___________ ___________

Cols_12 33.933 4.1264

Cols_34 36.908 4.1444

Cols_56 36.537 4.1513

and:

KSSV
on 6 Mar 2020

- Load the excel file into MATLAB using xlsread.
- Divide the data into sections using data1 = data(1:1000,:) ; data2 = data(1001:2000,:) ;
- Fit the staright line to each data/ curve using polyfit. Evaluate the values using polyval.
- Find the intersection of lines using InterX available from the link: https://in.mathworks.com/matlabcentral/fileexchange/22441-curve-intersections?focused=5165138&tab=function

KSSV
on 6 Mar 2020

Image Analyst
on 6 Mar 2020

How is this different than your duplicate question that I answered here:

KSSV
on 6 Mar 2020

Opportunities for recent engineering grads.

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

Start Hunting!
## 0 Comments

Sign in to comment.