# Plotting and finding the intersection of 2 curves

631 views (last 30 days)

Show older comments

##### 4 Comments

Image Analyst
on 17 Dec 2020

Sell = [12,22,28]

Price1 = [15,30,50]

Buy = [10,18,29]

Price2 = [25,42,50]

plot(Sell, Price1, 'b.-', 'LineWidth', 2, 'MarkerSize', 20);

grid on;

hold on;

plot(Buy, Price2, 'r.-', 'LineWidth', 2, 'MarkerSize', 20);

legend('Sell', 'Buy', 'location', 'southeast');

### Answers (2)

Paul Hoffrichter
on 17 Dec 2020

If you have two vectors, x1, y1 that form the curve (x1, y1), and likewise, another curve (x2, y2), then you can get the intersection points using the function by Douglas Schwarz.

or from this function by NS.

##### 0 Comments

Image Analyst
on 18 Dec 2020

For the specific case at hand:

Sell = [12,22,28]

Price1 = [15,30,50]

Buy = [10,18,29]

Price2 = [25,42,50]

plot(Sell, Price1, 'b.-', 'LineWidth', 2, 'MarkerSize', 20);

grid on;

hold on;

plot(Buy, Price2, 'r.-', 'LineWidth', 2, 'MarkerSize', 20);

legend('Sell', 'Buy', 'location', 'southwest');

xlabel('Sell or Buy Price in $', 'FontSize', 20);

ylabel('Price1 or Price2 in $', 'FontSize', 20);

% Get equations for the last two line segments.

coeff1 = polyfit(Sell(2:3), Price1(2:3), 1)

coeff2 = polyfit(Buy(2:3), Price2(2:3), 1)

% Find out where the lines are equal.

% ax + b = cx + d. Find x

% x = (d-b) / (a-c)

matchPrice = (coeff2(2) - coeff1(2)) / (coeff1(1) - coeff2(1))

y = coeff1(1) * matchPrice + coeff1(2)

caption = sprintf('Match at x = $%.2f, y = $%.2f', matchPrice, y);

title(caption, 'FontSize', 20);

% Draw lines in dark green color.

darkGreen = [0, 0.5, 0];

line([matchPrice, matchPrice], [0, y], 'Color', darkGreen, 'LineWidth', 2);

line([0, matchPrice], [y, y], 'Color', darkGreen, 'LineWidth', 2);

fprintf('Done running %s.m ...\n', mfilename);

##### 9 Comments

Image Analyst
on 21 Dec 2020

OK, I had to put in some lines to repair bad data, like your duplicated Sell prices at 49 (elements 25 and 26). That data repair is in between the --------- lines. Not only does the data repair make it more robust, but the final result does not depend on the curve having a linear relationship. The buy/sell/price plots could be curved. Yay!

Here is the final code and it will be accurate to 1/1000th of a cent.

clc; % Clear the command window.

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

clear; % Erase all existing variables. Or clearvars if you want.

workspace; % Make sure the workspace panel is showing.

format long g;

format compact;

data = readmatrix('sample data.xlsx');

Sell = data(:, 3);

Price1 = data(:, 2);

Buy = data(:, 1);

Price2 = data(:, 4);

p1 = plot(Sell, Price1, 'b-', 'LineWidth', 2, 'MarkerSize', 20);

grid on;

hold on;

p2 = plot(Buy, Price2, 'r-', 'LineWidth', 2, 'MarkerSize', 20);

legend([p1, p2], 'Sell', 'Buy', 'location', 'east');

xlabel('Sell or Buy Price in $', 'FontSize', 20);

ylabel('Price1 or Price2 in $', 'FontSize', 20);

%------------------------------------------------------------------------

% DATA REPAIR - FIX BAD DATA

% Now we have a problem with the supplied "Sell" data and need to fix it.

% If some of the "x" arrays have the same price more than once,

% the interpolation step will fail. So we need to average together any duplicates.

[Sell, sortOrder] = sort(Sell, 'Ascend'); % first sort from least to greatest.

% Now sort Price1 the same way.

Price1 = Price1(sortOrder);

% Now we can average all Price1 that have the same Sell price.

Price1 = splitapply(@mean, Price1, findgroups(Sell));

Sell = unique(Sell);

% Now fix Buy and Price2 the same way: (Actually in the supplied data, these arrays were OK.)

[Buy, sortOrder] = sort(Buy, 'Ascend'); % first sort from least to greatest.

% Now sort Price1 the same way.

Price2 = Price2(sortOrder);

% Now we can average all Price1 that have the same Sell price.

Price2 = splitapply(@mean, Price2, findgroups(Buy));

Buy = unique(Buy);

%------------------------------------------------------------------------

% Find the overall range

minPrice = min([Sell; Price1; Buy; Price2])

maxPrice = max([Sell; Price1; Buy; Price2])

% Interpolate extra points to get more accuracy for non-linear curves.

% We'll get to the nearest 1/1000 of a cent.

numPoints = (maxPrice - minPrice) * 1000;

% Get all possible "x" values.

x = linspace(minPrice, maxPrice, numPoints);

% Interpolate the other arrays at the new x points.

Price1a = interp1(Sell, Price1, x);

Price2a = interp1(Buy , Price2, x);

% Find differences at every x value.

priceDifference = abs(Price2a - Price1a);

% Find there the difference is minimum

[minDiff, indexOfMinDiff] = min(priceDifference)

% Get the x value there.

xMatch = x(indexOfMinDiff);

% Find out where the lines are equal.

% ax + b = cx + d. Find x

% x = (d-b) / (a-c)

matchPrice1 = Price1a(indexOfMinDiff)

matchPrice2 = Price2a(indexOfMinDiff)

yMatch = mean([matchPrice1, matchPrice2])

caption = sprintf('Match at x = $%.2f, y = $%.2f', xMatch, yMatch);

title(caption, 'FontSize', 20);

% Draw lines in dark green color.

darkGreen = [0, 0.5, 0];

line([xMatch, xMatch], [0, yMatch], 'Color', darkGreen, 'LineWidth', 2);

line([0, xMatch], [yMatch, yMatch], 'Color', darkGreen, 'LineWidth', 2);

% Legend will update to show these lines but we don't want them.

% so tell legend to only have the two plot lines.

legend([p1, p2], 'Sell', 'Buy', 'location', 'east');

fprintf('Done running %s.m ...\n', mfilename);

### See Also

### Categories

### Products

### Community Treasure Hunt

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

Start Hunting!