I am puzzled about how to plot the SinglePredictionBands
associated with a FittedModel
(e.g. LinearModelFit
) that is supplied as a variable.
The reasons I am interested in this are:
- I want to create some plot definitions to reuse;
- I want to include the graphics as arguments to
Manipulate
.
Please see the following code. The embedded comments explain what works and what doesn't.
dataTest = {{0, 1}, {1, 0}, {3, 2}, {5, 4}};
(* Explicit code works: both the fit and the bounds are plotted. The name of the dummy variable doesn't matter here. *)
lm = LinearModelFit[dataTest[[1 ;; 3]], {xVar}, {xVar}]
spb[xVar_] = lm["SinglePredictionBands"]
Plot[{lm[x], spb[x]}, {x, 0, 5}, PlotLabel -> "Explicit (argument x)"]
Plot[{lm[xVar], spb[xVar]}, {xVar, 0, 5}, PlotLabel -> "Explicit (argument xVar)"]
(* This delayed-evaluation code either plots only the fit (with x) or nothing (with xVar). *)
lmFn1[aaa_, bbb_] := LinearModelFit[dataTest[[aaa ;; bbb]], {xVar}, {xVar}]
spbFn1[fit_][xVar_] := fit["SinglePredictionBands"]
Plot[{lmFn1[1, 3][x], spbFn1[lmFn1[1, 3]][x]}, {x, 0, 5}, PlotLabel -> "Delayed1 (argument x)"]
Plot[{lmFn1[1, 3][xVar], spbFn1[lmFn1[1, 3]][xVar]}, {xVar, 0, 5}, PlotLabel -> "Delayed1 (argument xVar)"]
(* This hybrid code either plots only the fit (with x) or only the bounds (with xVar). *)
Plot[{lmFn1[1, 3][x], spbFn1[lm][x]}, {x, 0, 5}, PlotLabel -> "Delayed2 (argument x)"]
Plot[{lmFn1[1, 3][xVar], spbFn1[lm][xVar]}, {xVar, 0, 5}, PlotLabel -> "Delayed2 (argument xVar)"]
(* I had also tried the following, although it would be inefficient, because fitting the same data is repeated. *)
(* This alternative delayed-evaluation code either plots only the fit (with x) or nothing (with xVar).*)
pFn1[i_, j_] := Plot[{lmFn1[i, j][x], spbFn1[lmFn1[1, 3]][x]}, {x, 0, 5}, PlotLabel -> "Delayed3 (argument x)"]
pFn2[i_, j_] := Plot[{lmFn1[i, j][xVar], spbFn1[lmFn1[1, 3]][xVar]}, {xVar, 0, 5}, PlotLabel -> "Delayed3 (argument xVar)"]
pFn1[1, 3]
pFn2[1, 3]
Some of the problematic code generates errors like
"LinearModelFit::ivar: {0.000102143} is not a valid variable.
" (what's visible is actually "LinearModelFit: {0.000102143} is not a valid variable.
"), and some of it fails silently.
I've spent time trying many different configurations, and none worked. I'd appreciate an explanation of why the above-indicated lines of code don't work, and how they could be improved (preferably a simple way to improve them).
As a final aside, I haven't yet combined this with a Manipulate
statement, but I am envisaging doing it with a subsequent Dynamic
statement.
—DIV
P.S. After spending time debugging I did find a handful of posts on possibly related themes
- Manipulating a Plot of a FittedModel
- How to pass a symbol name to a function with any of the Hold attributes?
- Enforcing correct variable bindings and avoiding renamings for conflicting variables in nested scoping constructs
But that was not sufficient to clarify to me what the underlying problem is, nor how to fix it.