How are parameters evaluated for a Plot in Manipulate
The problem is that inside the Manipulate
, m1
and m2
are replaced with localized versions (as in Module
) rather than assigned (as in Block
). Since the m1
and m2
from bigA
are outside the Manipulate
, and bigA[t]
is evaluated only after the replacement of m1
and m2
inside the Manipulate
, they are not affected by the manipulation.
The best solution is to give m1
and m2
as extra arguments:
bigA[t_, m1_, m2_] := (m1+m2) ((m1 m2 t)/(m1+m2)^3)^0.25
Manipulate[Plot[bigA[t, m1, m2], {t, 1, 10}],
{{m1, 1.4}, 0.8, 3},
{{m2, 1.4}, 0.8, 3}]
If for some reason you cannot do that, you can also use replacement rules as follows:
bigA[t_] := (m1+m2) ((m1 m2 t)/(m1+m2)^3)^0.25
Manipulate[Plot[bigA[t]/.{m1->mm1,m2->mm2}, {t, 1, 10}],
{{mm1, 1.4}, 0.8, 3},
{{mm2, 1.4}, 0.8, 3}]
This works because ReplaceAll
(/.
) does the replacements only after the left hand side has been evaluated, and the mm1
and mm2
are now inside the Manipulate
, so they can be properly localized.
About your edit:
By adding Evaluate@
at the beginning of the argument to Manipulate
, you override Mathematica's order of evaluation. So with
Manipulate[Evaluate@bigA[t],
{{m1, 1.4}, 0.8, 3},
{{m2, 1.4}, 0.8, 3}]
Mathematica first evaluates bigA[t]
to (m1+m2) ((m1 m2 t)/(m1+m2)^3)^0.25
, and only then proceeds to evaluate the Manipulate
, which therefore sees the m1
and m2
.
Now this will not work with Plot
, because the whole Plot
statement will be executed, before Manipulate
will have a chance to insert m1
and m2
. So when Plot
evaluates bigA[t]
, it will receive an expression containing m1
and m2
instead of a number, and thus produce an empty graph. This graph (which no longer contains any trace of m1
or m2
) will then be passed to Manipulate
. Of course replacing m1
and m2
at this stage doesn't work, because they already vanished.
So in essence, while without Evaluate
, m1
and m2
are substituted too late, with Evaluate@Plot
they are consumed too early.
Now you might have the idea to use Manipulate[Plot[Evaluate@bigA[t],...],...]
instead, in order to evaluate bigA[t]
(to get m1
and m2
visible) but not Plot
(because that only works after m1
and m2
got a value). However that doesn't work either, because Evaluate
only affects order of evaluation when it appears as immediate argument of the expression being evaluated. So while evaluating Manipulate
, the Evaluate
in the argument of Plot
is not considered. It will be considered at the time Plot
is evaluated, but at that time it's already too late.
A couple of tips:
- Make sure you evaluate the function - best way is to put it in
Initialization :> ...
- Rather keep parameters m1, m2 as arguments
- Fix
PlotRange
to see function change, not the axes scale - Use
SaveDefinitions -> True
so interface will remember your defined function when you reopen notebook
I updated the code below to encompass your derivative question:
Manipulate[Plot[Evaluate@{bigA[t, m1, m2], D[bigA[t, m1, m2], t]}, {t, 1, 10},
PlotRange -> {0, 3}, Filling -> 0], {{m1, 1.4}, 0.8, 3}, {{m2, 1.4}, 0.8, 3},
Initialization :> (bigA[t_, m1_, m2_] := (m1 + m2) ((m1 m2 t)/(m1 + m2)^3)^0.25),
SaveDefinitions -> True]
Manipulate
does not temporarily change the global value of its variables, as does Table
and Do
. Compare:
Dynamic[x]
Do[Pause[1], {x, 0, 10}]
With:
Dynamic[x]
Manipulate[x, {x, 0, 10}]
Since your definition of bigA
relies on Global`
symbols m1
and m2
you must manually change these values, e.g. using Block
:
bigA[t_] := (m1 + m2) ((m1 m2 t)/(m1 + m2)^3)^0.25
Manipulate[
Block[{m1 = mm1, m2 = mm2},
Plot[bigA[t], {t, 1, 10}]
],
{{mm1, 1.4}, 0.8, 3},
{{mm2, 1.4}, 0.8, 3}
]
Or you could insert the definition of bigA
into manipulate using With
so that it appears explicitly (assuming no global values for m1
, m2
, or t
):
With[{x = bigA[t]},
Manipulate[
Plot[x, {t, 1, 10}],
{{m1, 1.4}, 0.8, 3},
{{m2, 1.4}, 0.8, 3}
]
]
Simpler and cleaner is to just parametrize m1
and m2
as belisarius shows.