3
$\begingroup$

I’m doing a little project for Wolfram Demonstration. When I create snapshots, i.e. paste several times Output cell of Manipulate, all of them updates simultaneously, if any control is changed.
I understand it’s about localizing variables, trying to apply Module inside and outside - nothing helps.

This demo-code repeats the key features of my project. It is undesirable to abandon Dynamic or TrackingFunction. It is also important that pts are updated completely only after num change, not steps.

I’m sure the problem is in pts variable, but I don’t know how to localize it while retaining the core features of the project.

Clear[mainStep]; Manipulate[
 pts = RandomReal[{0, 1}, {num, 2}];
 mainStep[data_] := If[Length@data > 1, Rest@data, data];
 Dynamic[Graphics[Point@pts, ImageSize -> 100]],

 {{num, 10}, 5, 20, 1, ContinuousAction -> False},

 {steps, 1, 10, 1,
  TrackingFunction -> (steps = #; pts = mainStep[pts]; &)
  },
 TrackedSymbols :> {num}]
$\endgroup$

2 Answers 2

4
$\begingroup$

Rule of thumb: if you're localizing something related to dynamics, use DynamicModule:

DynamicModule[{pts},
 Manipulate[pts = RandomReal[{0, 1}, {num, 2}];
  Dynamic[Graphics[Point@pts, ImageSize -> 100]], {{num, 10}, 5, 20, 1, 
   ContinuousAction -> False}, {steps, 1, 10, 1, 
   TrackingFunction -> (steps = #; pts = mainStep[pts]; &)}, 
  Initialization :> (Clear[mainStep]; 
    mainStep[data_] := If[Length@data > 1, Rest@data, data];), 
  TrackedSymbols :> {num}]]

I've also moved the definition of mainStep to Initialization option, this isn't necessary, but a little better because then the definition of mainStep will be evaluated only once.

$\endgroup$
1
  • $\begingroup$ Yes, many thanks, now each snap works separately! The only point - the rules of Wolfram Demonstrations require that the outer wrapper always was Manipulate. But since everything works, I hope there will be no problems $\endgroup$
    – lesobrod
    Aug 24, 2023 at 8:56
3
$\begingroup$

Here is another option. This uses the second argument of dynamics. No need to make separate function mainStep as you can do this directly in the second argument slot.

With this method, you just need to initialize the variables num and steps and pts to initial values using the None type for Dynamics, which was introduced I think in version 7 or 9 of Mathematica.

See if this does what you want.

enter image description here

Manipulate[
 Dynamic@Graphics[Point@pts, ImageSize -> {200, 200}],
 Grid[{{"steps", Manipulator[Dynamic[steps, {steps =#; pts = If[Length@pts > 1, Rest@pts, pts]} &], {5, 20, 1}, 
     ImageSize -> Tiny], Dynamic@steps},
   {"num", Manipulator[Dynamic[num, {num = #; pts = RandomReal[{0, 1}, {num, 2}]} &], {5, 20, 1}, 
     ImageSize -> Tiny, ContinuousAction -> False], Dynamic@num}
   }],

 (*initialize all Manipulate variables once*)
 {{steps, 5}, None},
 {{num, 10}, None},
 {{pts, RandomReal[{0, 1}, {10, 2}]}, None},

 TrackedSymbols :> {num}
 ]
$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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