Is it possible to find out which variable changed in manipulate?

I've got a solution here, but it's kludgy, and I wonder if there is any way to get this information directly from the system?

(If you have any trouble understanding the question, just run this code, which works correctly.)

   ControlChanged[parameters_List] := 
         Position[MapThread[UnsameQ, {oldParams, parameters}], True][[1, 1]], 
         oldParams = parameters; 

   ControlChanged[{x, y, z}], 
   {x, 0, 1}, 
   {y, 0, 1},
   {z, 0, 1}]
  • $\begingroup$ It may matter what do you want and what do you want to use it for. Is the index all you need? $\endgroup$
    – Kuba
    Oct 11, 2016 at 18:29
  • $\begingroup$ Sure. I want to recalculate based on what changed. I have a large set of variables which have relations, e.g. x + y == 1. If the user changes x, I want to recalculate y and leave x alone. If the user changes y, I want to recalculate x and leave y alone. $\endgroup$ Oct 11, 2016 at 20:28
  • $\begingroup$ If the user changes x, I want to recalculate y and leave x alone. If the user changes y, I want to recalculate x and leave y alone be careful with this. You'll end up in an infinite loop. If you modify a control variable inside Manipulate expression, it will automatically trigger another update and you will easily go to infinite loop, having to terminate the kernel from task bar. The basic rule of thumb is Manipulate, is to treat control variables as read-only. There are ways to work around this, but this will require different design. $\endgroup$
    – Nasser
    Oct 12, 2016 at 1:12

2 Answers 2


Here's a function track[var] that will set a "tracking" variable var to the held variable which changes. Just use it as the setting for TrackingFunction, wrapped with Evaluate[]. Why is Evaluate needed? Good question. It works with it and it doesn't work without it. Manipulate holds its arguments, but evaluates some of them at certain points during the construction of the output. In particular, it tests the option value for TrackingFunction. (It will revert to the default function, if the value is not a valid Function or List of functions.) Evidently, Evaluate is important somewhere along the line.

SetAttributes[track, HoldAll];
track[var_] := {Function[{val, u}, var = Hold[u], HoldRest], 
   Function[{val, u}, u = val, HoldRest], # &};
   {var, Hold[x], var === Hold[x]},
   Grid[{{x, y, z}}, Frame -> All, 
     Background -> {{Hold[x], Hold[y], Hold[z]} /. {var -> Red, _Hold -> None}, None}]
 {x, 0, 1, TrackingFunction -> Evaluate@track[var]},
 {y, 0, 1, TrackingFunction -> Evaluate@track[var]},
 {z, 0, 1, TrackingFunction -> Evaluate@track[var]},
 {{var, None}, None}]

Mathematica graphics

Mathematica graphics

Mathematica graphics

  • $\begingroup$ "TrackingFunction" is the sort of thing I was looking for. $\endgroup$ Oct 14, 2016 at 6:01
  • $\begingroup$ This duplicates the code I wrote above: $\endgroup$ Oct 14, 2016 at 22:52
  • $\begingroup$ Module[{cc}, cc = None; Manipulate[ cc, {x, 0, 1, TrackingFunction -> ((cc = 1; x = #) &)}, {y, 0, 1, TrackingFunction -> ((cc = 2; y = #) &)}, {z, 0, 1, TrackingFunction -> ((cc = 3; z = #) &)} ] ] $\endgroup$ Oct 14, 2016 at 22:53

If I understand you right, One way to do this, is to use the second argument of dynamics. Each dynamic control can use this as a place to record that it was selected, and update a common variable.

Then when Manipulate updates, simply examine this variable to see which control caused the Manipulate to update.

In this example, this common variable controlVariableName is just string of the name of the control, but you can make it anything else you want. Also the common variable controlVariableItself will contain the control variable value itself. i.e. x or y, etc...


   {Style[Row[{"changed [", controlVariableName, "] control!"}], Red],
   {Style[Row[{"Its current value [", controlVariableItself , "]"}], 
     Red], SpanFromLeft},
   {"x=", x, "y=", y, "z=", z}

     Dynamic[x, {x = #, controlVariableName = "x", 
        controlVariableItself = x} &], {0, 1, .1}, ImageSize -> Tiny],
     Dynamic[x]}, {"y", 
    Manipulator[Dynamic[y, {y = #, controlVariableName = "y", 
        controlVariableItself = y} &], {0, 1, .1}, ImageSize -> Tiny],
     Dynamic[y]}, {"z", 
    Manipulator[Dynamic[z, {z = #, controlVariableName = "z", 
        controlVariableItself = z} &], {0, 1, .1}, ImageSize -> Tiny],
     Text@Style["press me", 12], { controlVariableName = "Button", 
      controlVariableItself = "Button"}]}

 {{controlVariableName, "x"}, None},
 {{controlVariableItself, x}, None},
 {{x, 0}, None},
 {{y, 0}, None},
 {{z, 0}, None},
 TrackedSymbols :> {x, y, z}

enter image description here

  • $\begingroup$ This is more like it, but can I get to that second argument from Manipulate? Or do I have to break it all out that way? $\endgroup$ Oct 11, 2016 at 20:49
  • $\begingroup$ @CharlesGillingham If you mean pass the variable value itself, instead of just its name as string as in the example? Sure. I've updated the answer. $\endgroup$
    – Nasser
    Oct 11, 2016 at 22:31
  • $\begingroup$ These are interesting applications of the answer to this question. $\endgroup$ Oct 15, 2016 at 1:29
  • $\begingroup$ What I personally want to do is enforce constraints between a set of parameters. E.g. If x+y == 1, then I want {x,0,1,TrackingFunction->((x = #; y = 1 - x;&)} $\endgroup$ Oct 15, 2016 at 1:32

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.