I have read the documentation, and know the way Initialization works with Manipulate, but I can't seem to understand why this piece of code

 Plot[h[x], {x, -3, 3}]
 , {b, -5, 5}
 , Initialization :> (h[x_] := x + b)]

produces a static graph. I know that if I change the function h[x] to h[x_,b_], then the Manipulate gives a dynamic graph, but I would like the function h to have one parameter (instead of two), if possible.

What am I missing here? Thanks, as always, for all help!

  • 1
    $\begingroup$ Try h[x]/.b->b $\endgroup$ – Kuba Sep 14 '13 at 15:04
  • 3
    $\begingroup$ Since you don't say, I can't comment on your reasons for really wanting h to have only one parameter. But if it were my code, I find it difficult to imagine that I'd be happy with any variant of the one-parameter solution. $\endgroup$ – John Fultz Sep 14 '13 at 16:56
  • 2
    $\begingroup$ Because b is not explicitly present in the body of Manipulate it is not being tracked. You need to add TrackedSymbols :> {b} to the Manipulate options. $\endgroup$ – Simon Woods Sep 14 '13 at 18:21
  • 1
    $\begingroup$ @JohnFultz: I don't quite understand your comment: would you be happy with the one-parameter function h? Can you elaborate why yes/no? Thanks! $\endgroup$ – Gabriel Sep 14 '13 at 23:49
  • 1
    $\begingroup$ @Gabriel I'm thinking of Manipulate as a form of DynamicModule. DynamicModule does lexical scoping. It's generally a bad idea to assign a lexically scoped localized variable to a global symbol (as you are assigning h in terms of b). It's difficult to understand, it may not do what you want, and the behavior might change depending upon implementational details. Therefore, I would strongly prefer DynamicModule (and Module) variables to be passed directly as function arguments without side-effect assignments. $\endgroup$ – John Fultz Sep 15 '13 at 13:56

I'm posting this to get the answer in Simon Woods' comment on record.

Manipulate[Plot[h[x], {x, -3, 3}],
  {b, -5, 5},
  TrackedSymbols -> {b},
  Initialization :> (h[x_] := x + b)]

I think this is the simplest solution to the problem as posed.


The variable b is local inside the Manipulate. The Initialization construct acts just as if the initialization code was executed before the Manipulate -- hence is outside its scope. So it only looks like the b is inside the scope of the Manipulate.

If you really want to define h inside the Manipulate to have a single argument, you can accomplish it this way:

bOld = 100;
Manipulate[ If[bOld != b, h[x_] := x + b; bOld = b;]; 
            Plot[h[x], {x, -3, 3}], {b, -5, 5}]

The bOld and If are used to make sure the function does not continuously retrigger the evaluation and only redefines h[x] when needed (i.e., when b changes).


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.