# Plotting a list along with its trend line [duplicate]

Say I have these data:

data = {{1, 3}, {2, 4}, {3, 6}, {4, 7}};


I want to fit these data with a quadratic equation, like this:

Fit[data, {1, x}, x]


Mathematica then outputs $1.5 + 1.4x$. However, trying to plot this like this:

Plot[Fit[data, {1, x}, x], {x, 0, 5}]


Results in the errors

General::ivar: 0.00010214285714285715 is not a valid variable.
General::ivar: 0.00010214285714285715 is not a valid variable.
General::ivar: 0.10214295918367347 is not a valid variable.
General::stop: Further output of General::ivar will be suppressed during this calculation.


I tried copying the $1.5 + 1.4x$ directly into Plot, after which I saw that it did not actually say $1.5 + 1.4x$:

Plot[1.5000000000000009 + 1.3999999999999995 x, {x, 0, 5}]


So that's where the  came from. Surely removing them manually is not the way to go. What went wrong?

Plot has Attributes of HoldAll. This can be verified by:

Attributes@Plot


{HoldAll, Protected, ReadProtected}

...from the second point under Details and Options in the Plot documentation:

Plot has attribute HoldAll and evaluates [the function] only after assigning specific numerical values to [the independent variable].

So in your example, we want to force Plot to evaluate the Fit function before attempting to create the graphics:

Plot[Evaluate@Fit[data, {1, x}, x], {x, 0, 5}] and to combine with the data.

Show[{Plot[Evaluate@Fit[data, {1, x}, x], {x, 0, 5}],
ListPlot[data, PlotStyle -> ColorData[1, 2]]}]


or

Plot[Evaluate@Fit[data, {1, x}, x], {x, 0, 5}, Epilog -> {ColorData[1, 2], Point@data}] As to your second point, when you copy the output of Fit and paste it into the front end, a real number approximation is shown based on \$MachinePrecision.

• – Mr.Wizard Jun 2 '13 at 7:56

You can use LinearModelFit like this:

data={{1,3},{2,4},{3,6},{4,7}};
lmf=LinearModelFit[data,x,x];
p1=Plot[lmf[x],{x,0,5}];
p2=ListPlot[data,PlotStyle->{PointSize@Large,Red}];
Show[p1,p2]


To get: You could, of course, choose to use FindFit[] instead:

fitLine[x_] = a + b x /. FindFit[data, a + b x, {a, b}, x]

Plot[fitLine[x], {x, 0, 5}, Axes -> None,
Epilog -> {Directive[AbsolutePointSize, Red], Point[data]}, Frame -> True] This works, since FindFit[] returns a list of replacement rules for the coefficients:

FindFit[data, a + b x, {a, b}, x]
{a -> 1.5, b -> 1.4}


You can then use ReplaceAll[] (/.) to replace the coefficients in a + b x with the numerical values found by FindFit[]. (I used Set[] instead of SetDelayed[] so that the replacement is instantly done before the function fitLine[] is defined.)

• +1, however IMHO you should use formal symbols or add Block, or at least reference these methods. – Mr.Wizard Jun 2 '13 at 7:53
• Hmm, maybe later... – J. M. is in limbo Jun 2 '13 at 12:39