4

I would like to understand why this is not working:

replacement = {a[t] -> r};
Manipulate[Plot[a[t] /. replacement, {r, 0, 1}], {t, 1, 2}]

But this does:

Manipulate[Plot[a[t] /.{a[t] -> r}, {r, 0, 1}], {t, 1, 2}]

I suppose it has to do with the HoldAll Attribute of Manipulate but I am not sure and I also don't know how to resolve this issue.

Michael E2
  • 235,386
  • 17
  • 334
  • 747
Mr Puh
  • 1,017
  • 6
  • 12

2 Answers2

6

The problem is that Manipulate localizes its variables. It does this lexically, that is, the variables that appear in the actual text of the code body are localized, but not the ones that might appear when the code is evaluated. So the t in replacement is different than the t in the Manipulate. Sometimes it is important to keep the variables localized, so it is usually better (less bug-prone) to avoid applying Evaluate to the body, just in case the variables are given global values at some point in the kernel session.

One alternative is to construct the expression within Manipulate:

Manipulate[Plot[a[t] /. replacement, {r, 0, 1}],
 {t, 1, 2},
 {{replacement, {a[t] -> r}}, ControlType -> None}]

Another is to construct them as functions and pass the Manipulate parameters:

replacement[t_] := {a[t] -> r};
Manipulate[Plot[a[t] /. replacement[t], {r, 0, 1}], {t, 1, 2}]

Or all parameters:

replacement[a_, t_, r_] := {a[t] -> r};
Manipulate[Plot[a[t] /. replacement[a, t, r], {r, 0, 1}], {t, 1, 2}]
Michael E2
  • 235,386
  • 17
  • 334
  • 747
3

Try using Evaluate to force evaluation:

replacement = {a[t] -> r};
Manipulate[Evaluate[Plot[a[t] /. replacement, {r, 0, 1}]], {t, 1, 2}]
ktm
  • 4,242
  • 20
  • 28
  • 1
    Note that this does not work if the replacement value depends on t; for example, replacement = {a[t] -> r^t}. – Michael E2 Jan 03 '18 at 23:00