# Setting and getting values from a x-y graph

I have a bunch of x-y graphs given to me and I need to be able to transform them into some kind of data structure from which I will be able to get Y with X value.
The problem is, though that I have 4, at max 5 values of Y given to me, and my X values can range up to 9000. So the information I have is something of the form

``````Point # X       Y
1       1000    100
2       3250    460
3       6000    320
4       6500    300
``````

My idea initially was something like:

``````function getY(\$x){
\$data = 100;
\$data = 460;
\$data = 320;
\$data = 300;

if(isset(\$data[\$x])){
return \$data[\$x];
}

\$minKnown = null;
\$maxKnown = null;

foreach(\$data as \$_x => \$y){
if(\$_x < \$x){
\$minKnown = \$_x;
}

if(\$_x > \$x){
\$maxKnown = \$_x;
break;
}
}

return \$data[\$minKnown] + ((\$x - \$minKnown) / (\$maxKnown - \$minKnown)) * (\$data[\$maxKnown] - \$data[\$minKnown]);
``````

} }

This function I just wrote to illustrate my idea. Basically if a point is not defined but somewhere between 2 known points, assuming there are no curves between the two points get the value that co-responds to the position of X between the two known values of X. I'm not even sure if my verbal explanation is actually correct or not but I guess that's what I wrote the function for.

Anyway, I was thinking, since graphs something that's widely used, are there any better ways of doing this, and I'm hoping there are otherwise I might turn out to be smarter than I thought, which is scary.

• I think you are looking for either "linear interpolation" (with multiple points - which is what you're doing here!) or "splines" (different types but basically ways to approximate those curves - see here for more details). Unfortunately I don't see any good PHP libraries for this right away, unless you're trying to just plot smooth curves on the graph. Good job on getting something working! – J Trana Jan 9 '15 at 3:24

Since you said, that you assume that there are no curves, the graph itself would probably look like a stock development. So I would try a vector calculation approach. With the data you gave in your example you would get 3 vectors defined by two points. (To generalize it, you would get one vector less then you got points.)

Vector1: Point1->Point2 (Point2[x] - Point1[x], Point2[y] - Point1[y])
Vector2: Point2->Point3 (Point3[x] - Point2[x], Point3[y] - Point2[y])
Vector3: Point3->Point4 (Point4[x] - Point3[x], Point4[y] - Point3[y])

With values:

Vector1: (3250 - 1000, 460 - 100) = (2250, 360)
Vector2: (6000 - 3250, 320 - 460) = (2750, -140)
Vector3: (6500 - 6000, 300 - 320) = (500, -20)

Now the standard linear function has the form y = m*x + b. The vector itself won't need the b. So for Vector1 it is: 360 = m * 2250
Resolved for m we get: m = 360 / 2250 = 0.16 Now we get back to the original line between P1 and P2, which will require a value for b.
We get this now with: 100 = 0.16 * 1000 + b => b = -60 With that we know each y value between Point1 and Point2 will be defined by this equation: y = 0.16 * x - 60.
You can check this by simply inserting the values of one of the points into the equation: P1 100 = 1000 * 0.16 - 60
P2 460 = 3250 * 0.16 - 60

Code example:

``````\$vector1x = \$Point2->X - \$Point1->X;
\$vector1y = \$Point2->Y - \$Point1->Y;

\$m1 = \$vector1y / \$vector1x
\$b1 = \$Point1->y - \$Point1->x * \$m1
// do the same for the other points as described.
``````

Now when you get a value for x which you want to get the y value of do sth like this:

``````function getY(\$x)
{
if(\$x >= \$Point1->X && \$x <= \$Point2->X)
{
\$y = \$m1 * \$x + \$b1;
}
else if(\$x <= \$Point3->X)
{
\$y = \$m2 * \$x + \$b2;
}
else if(\$x <= \$Point4->X)
{
\$y = \$m3 * \$x + \$b3;
}
else
{
throw new Exception("Cannot calculate value with given data!");
}
return \$y;
}
``````

I hope this approach serves your needs and helps you in solving the problem.