5
$\begingroup$

I have a plot with interactive controls. I'd like to give the user the option between having the plot automatically update (when the plot's parameters are changed with the slider) and having the update happen only when an 'update' button is pushed. I've been spinning my wheels on this for a long time. Any and all help is appreciated.

$\endgroup$
4
  • 2
    $\begingroup$ Please provide a simple example. $\endgroup$ – bbgodfrey Jul 20 '16 at 20:54
  • 1
    $\begingroup$ By the way you might want to look at ContinuousAction if you have not done so already. It is not an answer to your question but it can provide a reasonable in-between in some cases. $\endgroup$ – Mr.Wizard Jul 20 '16 at 21:25
  • 1
    $\begingroup$ And if performance is an issue then ControlActive is good to know. $\endgroup$ – Kuba Jul 20 '16 at 21:26
  • 1
    $\begingroup$ @Kuba Good point! nibudd, please see (8072) for one example, or search the site for others $\endgroup$ – Mr.Wizard Jul 20 '16 at 21:27
10
$\begingroup$

Edit

Can you think of another way to accomplish the same thing [...]? It would be nice to have a solution that didn't involve duplicating each slider.

-nibudd

DynamicModule[{a = 1, tempA = 1, auto = True}
 ,
 ifAuto = Dynamic[
     If[auto, Identity, Setting]@#, 
     TrackedSymbols :> {auto}
 ] &;
 
 Column[{
   ifAuto @ Dynamic @ Plot[Sin[a x], {x, 0, 1}],
   Slider[Dynamic[a], {1, 10}],
   Checkbox[Dynamic[auto]],
   Button["Update", auto = True; FinishDynamic[]; auto = False;, 
    Method -> "Queued", Enabled -> Dynamic@Not@auto]
   }]
 ]
  • ifAuto function is meant to be used on Dynamic parts of GUI that you want to be affected by this behaviour.

  • ifAuto's Dynamic output is triggered only when variable auto changes

  • If auto === True then it acts as it wasn't there. E.g Dynamic[Plot[...]...] is shown and the FrontEnd will take care about its updates according to what was set there.

    If[ from ifauto is only run when auto changes so it does not affect the performance, neat. Read more in tutorial/AdvancedDynamicFunctionality/Nesting Dynamic

  • If auto === False then Setting @ Dynamic @ Plot[... is shown, effectively stripping Dynamics and leaving Plot[... which won't be updated by a's changes (because of the very outer TrackedSymbols:>{auto}.


Initial approach

The idea is to switch controllers between main a variable and a temporary one tempA's.

The Checkbox toggles that. It also makes both variables synchronized so that the transistion is "smooth".

DynamicModule[{a = 1, tempA = 1, auto = True},
 Column[{
   Dynamic @ Plot[Sin[a x], {x, 0, 1}],
   PaneSelector[
    {
     True -> Slider[Dynamic[a], {1, 10}],
     False -> Slider[Dynamic[tempA], {1, 10}]
     },
    Dynamic@auto
    ],
   Checkbox[Dynamic[auto, If[auto = #, a = tempA, tempA = a] &]],
   Button["Update", a = tempA, Enabled -> Dynamic@Not@auto]
   }
  ]
 ]

enter image description here

Instead of PaneSelector you can use

`Slider[Dynamic[tempA, (tempA = #; If[auto, a = tempA]) &], {1, 10}]`

but spamming If whenever you move a Slider is not neat.

$\endgroup$
7
  • $\begingroup$ This is exactly the kind of thing I was trying to achieve. Now to understand what you've done here - thank you! $\endgroup$ – nibudd Jul 20 '16 at 21:52
  • $\begingroup$ If you'll indulge me, I have some questions about how this works: 1. What is the If pure function taking as its argument, the value of Checkbox? 2. What is the meaning of auto = # in the first argument of If? Is # being evaluated to determine which expression to execute (a = tempA or tempA = a) and then assigning that value to auto? 2b. If so, why is that necessary? Isn't auto already tied to the Checkbox? 3. What is the meaning of @ here? I can't find any documentation on this kind of usage (Dynamic @ Plot[..., Dynamic @ auto, or Dynamic @ Not @ auto) $\endgroup$ – nibudd Jul 21 '16 at 15:45
  • 1
    $\begingroup$ @nibudd 1. take a look at docs for Dynamic, the second argument of Dynamic can be a function which does whatever you want with the state of the controller. # is a slot which will be filled with that state, so True or False. 2. auto = # has 2 roles, assigns Checkbox state to auto and returns this value so we can synchronize a with tempA (when a or tempA is active the other isn't though we don't want it's old value to pop up after switching). Hope that was clear. About @, take a look at What the @#%^&*?! $\endgroup$ – Kuba Jul 21 '16 at 16:22
  • $\begingroup$ I did read the documentation on Dynamic, but since I'm relatively new to Mathematica, I did not find it terribly helpful. I appreciate you clearing up my confusion. Can you think of another way to accomplish the same thing by using the TrackedSymbols attribute of Plot? I've been trying to do this with something like TrackedSymbols :> Dynamic[list, If[manualUpdate = #, list = {update}, list = {a, b}] &]' where update` is tied to my update button, and a, b are tied to two different sliders. It would be nice to have a solution that didn't involve duplicating each slider. $\endgroup$ – nibudd Jul 21 '16 at 16:52
  • 1
    $\begingroup$ @nibudd I see, take a look at the edit, that should be it. $\endgroup$ – Kuba Jul 21 '16 at 17:47

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.