How to plot Fit functions?

If I do something like this

f[x_]:=x^2

Plot[f[x],{x,1,10}]

Mathematica plots the function $f(x)=x^2$, as expected. However, if I do something like this instead

data=Table[x^2,{x,1,10}]

f[x_]:=Fit[data,{1,x},x]

Plot[f[x],{x,1,10}]

Mathematica throws me some weird errors such as -4.9998 is not a valid variable. What is going on here?

• As an aside, how is one supposed to go about typesetting multi-line code on this website? Is there a better way to do it than exiting the code environment, adding spaces, and entering the code environment again? Jul 20, 2012 at 16:07
• @JonathanGleason Are you using f[x_]:=... ? It seems you are missing the = sign. Jul 20, 2012 at 16:12
• @b.gatessucks Yeah, sorry about that. That was a typo on here. In Mathematica, I was using f[x_]:=.... Jul 20, 2012 at 16:13

The definition of your function f[x_] is the problem. Here is the corrected version:

data = Table[x^2, {x, 1, 10}]

(* ==> {1, 4, 9, 16, 25, 36, 49, 64, 81, 100} *)

f[x_] = Fit[data, {1, x}, x]

(* ==> -22. + 11. x *)

Plot[f[x], {x, 1, 10}]


The mistake was to define the function with SetDelayed. In that case, the symbol x on the right-hand side of the definition will be given the value with which the function is called, whereas Fit expects x to be a symbol and not a numeric value.

As an alternative, you can use FindFit[] instead of Fit[] for defining your regression function:

data = Table[x^2, {x, 1, 10}];
f = Function[x, a + b x] /. FindFit[data, a + b x, {a, b}, x];

Plot[f[x], {x, 1, 10}] ~Show~ ListPlot[data]


This hinges on the fact that FindFit[] returns the parameters (as replacement rules) as opposed to the regression function itself, making substitution into the regression model easy.

Mr. Wizard reminds me that variable localization might be necessary, especially if this is being done in the midst of a long session, where the variables may have had previous un-Clear[]ed assignments. One way to go about it is to use so-called "formal symbols" which are guaranteed to never have taken previous values, since you can's assign to them.

Here's how to go about it in this case:

f = Function[\[FormalX], \[FormalA] + \[FormalB] \[FormalX]] /.
FindFit[data, \[FormalA] + \[FormalB] \[FormalX], {\[FormalA], \[FormalB]}, \[FormalX]]


(It looks somewhat complicated here, since the SE interface does not have the proper font faces for the characters that denote formal symbols. It looks better when pasted into Mathematica.)

Also

data = Table[x^2, {x, 1, 10}];
f1 = Fit[data, {1, x}, x];
f2 = Fit[data, {1, x^2}, x];
Show[Plot[{f1, f2}, {x, 1, 10}], ListPlot@data]


Edit

Note that the following gives you the same result

data = Table[x^2, {x, 1, 10}];
f1 = Fit[data, {1, #}, x] & /@ {x, x x}
Show[Plot[f1, {x, 1, 10}], ListPlot@data]


An example:

data = {{0, 1}, {1, 0}, {3, 2}, {5, 4}}

f[x_] = Fit[data, {1, x}, x]

Plot[f[x], {x, 0, 10}]


Please note that I used = instead of :=. The right hand side needs to evaluate before being assigned to f.

• IMHO you should localize x in Fit. Jul 20, 2012 at 22:05
• Yeah. Probably. Jul 23, 2012 at 13:48

At present none of the answers given localize variables during the definition of f to protect against global assignments. For actual use I strongly suggest you do:

x = 0; (*example left-over assignment*)

data = {{0, 1}, {1, 0}, {3, 2}, {5, 4}}

Block[{x},
f[x_] = Fit[data, {1, x}, x]
]

Plot[f[x], {x, 0, 10}]


Or:

f[\[FormalX]_] = Fit[data, {1, \[FormalX]}, \[FormalX]]

Plot[f[x], {x, 0, 10}]


I also wrote a function localSet to answer a prior question which you could use:

x = 0; (*example left-over assignment*)

data = {{0, 1}, {1, 0}, {3, 2}, {5, 4}}

localSet[ f[x_], Fit[data, {1, x}, x] ]

DownValues[f]

{HoldPattern[f[x_]] :> 0.186441 + 0.694915 x}