8
$\begingroup$

Suppose I have two curves intersect at some point, how can I read the coordinates from the graph, not read by eye, but find it with more precision by computer.

For example, here are two lists created by simple functions just for illustration. However, the true list is not created by simple functions. So, using FindRoot is not welcomed. Also, do not assume the points is very dense, so that you can just find the coordinates from the two list with the shortest length. For the sparse points, the coordinates got in that way will have a large error.

For your convenience, you can start with the following code:

lst1 = Table[{x, x^2}, {x, 0, 5, 0.5}];
lst2 = Table[{x, x + 3}, {x, 0, 5, 0.5}];
GraphicsRow[{ListLinePlot[{lst1, lst2}], ListPlot[{lst1, lst2}]}]

enter image description here

$\endgroup$
3
  • $\begingroup$ ...actually, you can still use FindRoot[]. Build the piecewise linear interpolating function for both sets (use Interpolation[]), eyeball the possible intersection point, and use FindRoot[] to find the intersection of the two InterpolatingFunction[]s generated, using your eyeballed value as the seed. $\endgroup$ Commented Oct 31, 2015 at 15:21
  • $\begingroup$ @J.M. Thanks for your comment, I answered it myself. $\endgroup$ Commented Oct 31, 2015 at 15:28
  • $\begingroup$ Related question on Stack Overflow: (7779387) $\endgroup$
    – Mr.Wizard
    Commented Jul 22, 2016 at 16:04

3 Answers 3

12
$\begingroup$

The internal function Graphics`Mesh`FindIntersections has limitations that are not well understood, but it can be applied directly to plots. For normal plots, it has always worked for me. It will find all the intersections, too, if there are more than one.

lst1 = Table[{x, x^2}, {x, 0, 5, 0.5}];
lst2 = Table[{x, x + 3}, {x, 0, 5, 0.5}];
plot = ListLinePlot[{lst1, lst2}]

Graphics`Mesh`FindIntersections@plot
(*  {{2.28571, 5.28571}}  *)

To compare with the OP's answer using Interpolation, this method is equivalent to using InterpolationOrder -> 1.

f = Interpolation[lst1, InterpolationOrder -> 1];
g = Interpolation[lst2, InterpolationOrder -> 1];
{x, f[x]} /. FindRoot[f[x] == g[x], {x, 2.1}]
(*  {2.28571, 5.28571}  *)

The default interpolation order, which is cubic, gives a slightly different answer:

f = Interpolation[lst1];
g = Interpolation[lst2];
{x, f[x]} /. FindRoot[f[x] == g[x], {x, 2.1}]
(*  {2.30278, 5.30278}  *)

This agrees exactly with the roots of the functions used to construct the lists because those functions, x^2 and x + 3, have degrees that do not exceed the interpolation order (and there are a sufficient number of data points).

$\endgroup$
1
  • 1
    $\begingroup$ Note that whether the apparent improvement in accuracy from using the higher interpolation order is significant in a given problem should probably be considered in conjunction with the data, its source, and the model underlying the problem. $\endgroup$
    – Michael E2
    Commented Oct 31, 2015 at 16:23
7
$\begingroup$

Yet another way is to use the interpolation of one set of points as an appropriate mesh function in the plot of the other.

Here

mf = Interpolation[lst2];

and

plt = ListLinePlot[lst1, MeshFunctions -> (#2 - mf[#1] &), Mesh -> {{0}}, MeshStyle -> Red]

enter image description here

You can then extract the point with

plt// Cases[Normal@#, Point[a_] :> a, Infinity] &
(*{{2.28571, 5.28571}}*)
$\endgroup$
2
  • $\begingroup$ +1. Funny I just used this (some days ago) in this answer. $\endgroup$
    – Michael E2
    Commented Oct 31, 2015 at 17:43
  • $\begingroup$ @MichaelE2 I just +1'ed yours there, it's indeed the same idea! Silvia's answer on that question has got me thinking of mesh functions as useful things. $\endgroup$
    – gpap
    Commented Oct 31, 2015 at 18:08
6
$\begingroup$

Following the comment by @J.M., here is a solution:

lst1 = Table[{x, x^2}, {x, 0, 5, 0.5}];
lst2 = Table[{x, x + 3}, {x, 0, 5, 0.5}];
GraphicsRow[{ListLinePlot[{lst1, lst2}], ListPlot[{lst1, lst2}]}]
f = Interpolation[lst1];
g = Interpolation[lst2];
cords = {x = x /. FindRoot[f[x] == g[x], {x, 2.1}], f[x]}
cordsExact = {x /. FindRoot[x^2 == x + 3, {x, 2.1}], x^2}

cheers!

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.