Take the 2-minute tour ×
Mathematica Stack Exchange is a question and answer site for users of Mathematica. It's 100% free, no registration required.

Suppose I have a DynamicModule with all sorts of controls to set some parameters for a graphics object.

DynamicModule[{a = 0, b = 0},
  Column[{
    Slider[Dynamic[a]],
    Slider[Dynamic[b]],
    Dynamic[Plot[Sin[(a + 1) t + \[Pi] b], {t, 0, 2 \[Pi]}]]
  }]
]

This graph is updated every time one of the dynamic parameters change. Now pretend my graphics is a really slow 3D plot. How can I construct it so that it only renders the graphic when I tell it to? A button? A mouse event?

share|improve this question
add comment

3 Answers

up vote 13 down vote accepted

If you want the user to have absolute control over updates...say, by having an explicit Update button, then you can do so by adding an independent variable to control the updating and changing your Dynamic so that it only tracks that variable. Here, I introduce a variable update, which is an integer. Its value and type don't matter...what matter is that the Dynamic only updates when that variable does:

DynamicModule[{a = 0, b = 0, update = 0}, 
 Column[{Slider[Dynamic[a]], Slider[Dynamic[b]], 
   Button["Update", update++], 
   Dynamic[update; Plot[Sin[(a + 1) t + \[Pi] b], {t, 0, 2 \[Pi]}], 
    TrackedSymbols :> {update}]}]]
share|improve this answer
add comment

I think the following solves your problem. The option that you look for is ContinuousAction -> False. If you use Manipulate then using the same option you will get your requested update button. In the following once you decide where you want to locate your slider then only the computation will be initiated not continuously during the instantaneous slider movement

DynamicModule[{a = 0, b = 0}, 
Column[{Slider[Dynamic[a], {-3, 3, .01}, ContinuousAction -> False], 
Slider[Dynamic[b], {-3, 3, .01}, ContinuousAction -> False], 
Dynamic[Plot3D[Sin[a x + y^2 b], {x, -3, 3}, {y, -2, 2}, 
PlotPoints -> 140, Mesh -> None, MaxRecursion -> 3, 
ImageSize -> 400]], 
Dynamic["Time Count: " <> ToString@Clock[4]]}, 
Frame -> All]]

enter image description here

I used some options for Plot3D to generate a bit heavy graphics and also gave a reference clock cycle of four seconds to sense the computation time after the control triggers are decided.

share|improve this answer
add comment

Using ContinuousAction -> False is a good suggestion, and the simplest solution. If you'd prefer to get some real time feedback even during dragging the slider, you can use ControlActive to temporarily change the value of parameters that affect performance.

DynamicModule[{a = 0, b = 0},
 Column[
  {Slider[Dynamic[a]], Slider[Dynamic[b]],
   Dynamic[
    Plot3D[Sin[a x + b/y], {x, -3, 3}, {y, -2, 2},
     PlotPoints -> ControlActive[20, 100],
     MaxRecursion -> ControlActive[0, 3],
     Mesh -> None,
     ImageSize -> 400]]
   }]]

This is in fact automatically going to happen with the PerformanceGoal setting of functions. The default value of $PerformanceGoal, the value of which depends on relevant controls being active. You can test this using

DynamicModule[{a = 1}, 
 Column[{Slider[Dynamic[a]], Dynamic[{a, $PerformanceGoal}]}]]
share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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