Introduction to Dynamic

This tutorial describes the principles behind Dynamic, DynamicModule, and related functions, and goes into detail about how they interact with each other and with the rest of the Wolfram Language.

These functions are the foundation of the higher-level function Manipulate that provides a simple yet powerful way of creating a great many interactive examples, programs, and Demonstrations, all in a very convenient, though relatively rigid, structure. If that structure solves the problem at hand, you need look no further than Manipulate and you do not need to read this tutorial. However, do continue with this tutorial if you want to build a wider range of structures, including complex user interfaces.

This is a hands-on tutorial. You are expected to evaluate all the input lines as you reach them and watch what happens. The accompanying text will not make sense without evaluating as you read.

The Fundamental Principle of Dynamic

Ordinary Wolfram Language sessions consist of a series of static inputs and outputs, which form a record of calculations done in the order in which they were entered.

Evaluate each of these four input cells one after the other.
In[1]:=
Click for copyable input
In[2]:=
Click for copyable input
Out[2]=
In[1]:=
Click for copyable input
In[4]:=
Click for copyable input
Out[4]=

The first output still shows the value from when x was 5, even though it is now 7. This is, of course, very useful, if you want to see a history of what you have been doing. However, you may often want a fundamentally different kind of output, one that is automatically updated to always reflect its current value. This new kind of output is provided by Dynamic.

Evaluate the following cell; note that the result will be 49 because the current value of x is 7.
In[5]:=
Click for copyable input

In fact it is generally the case that when you first evaluate an input that contains variables wrapped in Dynamic, you will get the same result as you would have without Dynamic. But if you subsequently change the value of the variables, the displayed output will change retroactively.

Evaluate the following cells one at a time, and note the change in the value displayed above.
In[6]:=
Click for copyable input
In[7]:=
Click for copyable input
In[8]:=
Click for copyable input

The first two static outputs are still 25 and 49 respectively, but the single dynamic output now displays 100, the square of the last value of x. (This sentence will, of course, become incorrect as soon as the value of x is changed again.)

There are no restrictions on the kinds of values that can go into a dynamic output. Just because x was initially a number does not mean it cannot become a formula or even a graphic in subsequent evaluations. This might seem like a simple feature, but it is the basis for a very powerful set of interactive capabilities.

Each time the value of x is changed, the dynamic output above is updated automatically. (You might need to scroll back to see it.)
In[9]:=
Click for copyable input
In[10]:=
Click for copyable input
In[1]:=
Click for copyable input
Dynamic[expr]an object that displays as the dynamically updated current value of expr

Basic dynamic expression.

Dynamic and Controls

Dynamic is often used in connection with controls such as sliders and checkboxes. The full range of controls available in the Wolfram Language is discussed in "Control Objects"; here sliders are used to illustrate how things work. The principles of using Dynamic with other controls is basically the same.

A slider is created by evaluating the Slider function, in which the first argument is the position and the optional second argument specifies the range and step size, with the default range from 0 to 1 and the default step size 0.

This is a slider in a centered position.
In[11]:=
Click for copyable input
Out[11]=

Click on the thumb and move it around. The thumb moves, but nothing else happens since the slider is not connected to anything.

This associates the position of the slider with the current value of the variable x. (This form is explained in more detail later.)
In[12]:=
Click for copyable input
Out[13]=
This creates a new dynamic output of x since the last one has probably scrolled off your screen by now.
In[14]:=
Click for copyable input
Out[14]=

Drag the last slider around. As the slider moves, the value of x changes and the dynamic output updates in real time.

The slider also responds to changes in the value of x.

To see this, evaluate this line.
In[15]:=
Click for copyable input

You should see the slider jump, and the dynamic output of x change, simultaneously.

This creates another x slider.
In[16]:=
Click for copyable input
Out[16]=

Notice that if you move either of the two sliders you now have, the other one moves in "lock sync". Both are connected, dynamically and bidirectionally, to the current value of x.

Dynamic and Other Functions

Dynamic and control constructs such as Slider are in many ways just like any other functions in the Wolfram Language. They can occur anywhere in an output, in tables, and even inside typeset mathematical expressions. Wherever these functions occur, they carry with them the behavior of dynamically displaying or changing in real time the current value of the expression or variable they are linked to. Dynamic is a simple building block, but the rest of the Wolfram Language turns it into a flexible tool for creating nimble, zippy, and often fun little interactive displays.

This makes a table of x sliders, which are updated in sync.
In[2]:=
Click for copyable input
Out[2]=
You can combine a slider with a display of its current value in a single output.
In[3]:=
Click for copyable input
Out[3]=
The great power of Dynamic lies in the fact that it can display any function of x just as easily.
In[20]:=
Click for copyable input
Out[20]=
Using integer-valued sliders, you can create dynamically updated algebraic expressions.
In[21]:=
Click for copyable input
Out[21]=
You can use dynamic expressions with Panel, Row, Column, Grid, and other formatting constructs.
In[22]:=
Click for copyable input
Out[22]=

Notice that the last example resembles the output of Manipulate. This is no coincidence, because Manipulate in fact produces a combination of Dynamic, controls, and formatting constructs, not fundamentally different from what you can do yourself using these lower-level functions.

Localizing Variables in Dynamic Output

Here is another copy of a slider connected to a simple plot.
In[23]:=
Click for copyable input
Out[23]=
This is a slider connected to another function.
In[24]:=
Click for copyable input
Out[24]=

If you have both these outputs visible and drag either slider, you will notice that they are communicating with each other. Move the slider in one example, and the other example moves too. This is because you are using the global variable x in both examples. Although this can be very useful in some situations, most of the time you would probably be happier if these two sliders could be moved independently. The solution is a function called DynamicModule.

DynamicModule[{x,y,},expr]an object which maintains the same local instance of the symbols x, y, in the course of all evaluations of Dynamic objects in expr
DynamicModule[{x=x0,y=y0},expr]specifies initial values for x, y,

Localizing and initializing variables for Dynamic objects.

DynamicModule has arguments identical to Module and is similarly used to localize and initialize variables, but there are important differences in how they operate.

Here are the same two examples with "private" values of x.
In[25]:=
Click for copyable input
Out[25]=
Notice that these two examples now work independently of each other.
In[26]:=
Click for copyable input
Out[26]=
Multiple instances of DynamicModule can be placed in a single output, and they maintain separate values of the variables associated with their respective areas in the output.
In[27]:=
Click for copyable input
Out[27]=

You might be tempted to use Module in place of DynamicModule, and in fact this would appear to work at first. However, it is not a good idea for several reasons, which are discussed in more detail in "Advanced Dynamic Functionality".

DynamicModule does its work in the front end, not in the kernel. It remains unchanged by evaluation, and when formatted as output, it creates an invisible object, embedded in the output expression that handles the localization. As long as that space of output remains in existence (i.e. is not deleted), the invisible object representing the DynamicModule will maintain the values of the variables, allowing them to be used in subsequent evaluations of Dynamic expressions within the scope (area) of the DynamicModule.

If you save a notebook containing a DynamicModule, close that notebook, then later reopen it in a new Wolfram System session, the values of all the local variables will still be preserved and the sliders inside the DynamicModule will be in the same positions. This will not be the case with sliders linked to global variables (like the earliest examples in this tutorial), nor with sliders linked to variables localized with Module instead of DynamicModule. Such variables store their values in the current Wolfram Language kernel session, and they are lost as soon as you quit the Wolfram System.

In addition to localizing variables to particular regions of output, DynamicModule provides options to automatically initialize function definitions when an expression containing a DynamicModule is opened, and to clean up values when the expression is closed or deleted. More details are found in DynamicModule.

The Second Argument of Dynamic

Dynamic connections are by default bidirectional. Sliders connected to a variable move together because they both reflect and control the value of the same variable. When you drag a slider thumb, the system constructs and evaluates expressions of the form , where expr is the expression given in the first argument to Dynamic and new is the proposed new value determined by where you have dragged the slider thumb. If the assignment can be done, the new value is accepted. If the assignment fails, the slider will not move.

These two sliders move in opposite directions when you move the first one. However, trying to move the second slider gives an error because you cannot assign a new value to the expression .
In[1]:=
Click for copyable input
Out[1]=

You can keep an arbitrary expression in the first argument of Dynamic, but change the dynamically executed evaluation by using the optional second argument. This is a convenient way to specify "inverse functions" that update the values of variables in the first arguments. The Wolfram Language does not attempt to deduce such inverse functions automatically from the first argument of Dynamic; you have to supply one yourself.

Dynamic[expr,f]continually evaluates during interactive changing or editing of val

Inverse functions.

This specifies how the value of x is to be updated and makes the second slider interactive. You can move either slider and the other slider responds by moving in the opposite direction.
In[30]:=
Click for copyable input
Out[30]=

Now the dynamically executed expression in the second slider is the pure function , which is given the proposed new value in . Note that the function is responsible for actually doing the assignment to whatever variable you want to change; you cannot just say if you want to change .

The ability to interpose your own arbitrary function between the mouse position and the state of the Wolfram System is very powerful, and you can use it for purposes beyond simple inverse functions. The function given in the second argument is effectively free to do anything it wants.

This defines "detents" that snap the slider to integer values if the thumb is within a certain tolerance of a round number.
In[31]:=
Click for copyable input
Out[31]=
This makes the variable take on rational numbers (integer fractions) instead of decimals.
In[32]:=
Click for copyable input
Out[32]=

For complete control over the tracking behavior, it is possible to specify separate functions that are called at the start, middle, and end of a mouse click on the slider thumb. If you are familiar with conventional userinterface programming, you will recognize these as separate, high-level event functions for the mousedown, mousedrag, and mouseup events.

This changes the background color while the click-and-drag operation is underway.
In[33]:=
Click for copyable input
Out[33]=

The second argument of Dynamic also lets you restrict the movement of a slider and effectively implement geometric constraints.

You can only move the thumb of this Slider2D along a circle.
In[34]:=
Click for copyable input
Out[34]=

Where Should Dynamic Be Placed in an Expression?

The fundamental behavior of Dynamic is to build a copy of the input expression into the output cell. To be more specific, Dynamic has the attribute HoldFirst and remains unchanged by evaluation.

The result of evaluating Dynamic[x+y] is Dynamic[x+y], which you can see by examining the InputForm representation of the output.
In[35]:=
Click for copyable input
Out[35]//InputForm=

You do not see Dynamic in ordinary output because, when formatted for display in the front end, Dynamic[x+y] is represented by an object that contains a copy of the unevaluated input (), but displays as the evaluated value of that expression. The Dynamic wrapper is still present in the output, but it is invisible.

Because Dynamic does its work entirely in the front end, you cannot use it inside functions that need to access the value of an expression in order to do their work.

For example, this works.
In[36]:=
Click for copyable input
Out[36]=
But this does not.
In[37]:=
Click for copyable input
Out[37]=

The Plot command needs to have specific numerical values for x to make a plot, but the Dynamic[x] inside the function being plotted does not evaluate into anything in the kernel. It remains inert as Dynamic[x], preventing the Plot command from doing anything sensible.

Another way to look at it is that the expression inside a Plot command does not appear directly anywhere in the output. Dynamic is a formatting function that does its work in the front end, not in the kernel, so if it is used in a way where it will never be placed as output, it is probably a mistake.

When combining Dynamic with controls, it is particularly important to get the Dynamic in the right place.

This example works as expected; move the slider and the value of x changes.
In[38]:=
Click for copyable input
Out[38]=
This example looks good at first, but if you move the slider, x does not change.
In[39]:=
Click for copyable input
Out[39]=

That is because when the Dynamic wrapped around Slider[x] evaluates its contents, the value of x is substituted, and the result is a slider whose first argument is a specific number, with no trace of the variable name left. The slider in this case is a dynamic display of a static slider.

What is needed is a static slider, which contains within it a dynamic reference to the value of the variable. In the case of controls, there is a simple rule for where to put the Dynamic. The first argument of any control function, such as Slider, Checkbox, or PopupMenu, will almost always be Dynamic[var].

Beyond these cases where Dynamic will not work in a particular position, there is often a great deal of flexibility about where to place Dynamic. It is often used as the outermost function in an input expression, but this is by no means necessary, and in more sophisticated applications, Dynamic is usually used deeper in the expression and can even be nested.

This displays a table of 10 copies of the value of x.
In[40]:=
Click for copyable input
Out[40]=

Dynamic is wrapped around the whole expression, so evaluation of the Table command is delayed until the output is displayed in the notebook. Any time the value of x is changed, the Table command will be reevaluated.

The output from this example looks exactly the same.
In[41]:=
Click for copyable input
Out[41]=

But in this case the Table command is evaluated immediately, generating a list of 10 separate Dynamic expressions, each of which evaluates x separately after the overall result has been placed in the notebook.

When x is changed, the first example sends a single request to the kernel to get the value of Table[x,{i,10}], while the second example sends 10 separate requests to the kernel to get the value of x. It might seem that the first example is obviously more efficient, and in this case it is. However, you should also avoid the other extreme: wrapping too many things into a single Dynamic, which can also be inefficient.

This initializes x and y to set up a new slider connected to the value of x.
In[6]:=
Click for copyable input
In[7]:=
Click for copyable input
In[8]:=
Click for copyable input
Out[8]=
This is a tab view with two groups of dynamic expressions, both showing the dynamic values of x (a simple number) and y (a 3D plot).
In[9]:=
Click for copyable input
Out[9]=

Drag the slider around, and note that the value of x in the first tab updates quite rapidly. On most computers it will be essentially instantaneous. However, updates are more sluggish in the second tab. Each individual Dynamic expression keeps track (quite carefully) of exactly when it might need to be reevaluated in order to remain up to date. In the second tab, the output is forcing the whole expression , including the large, slow 3D plot, to be reevaluated every time the value of x changes. By using two separate Dynamic expressions in the first tab, you allow the value of x to be updated without needing to also reevaluate y, which has not actually changed. (You may want to delete the last output before proceeding, as it will slow down any examples containing the global x as long as it is visible on screen.)

It is hard to make blanket statements about where Dynamic should be placed in every case, but generally speaking if you are building a large, complex output where only small parts of it will change, the Dynamic should probably be wrapped just around those parts. On the other hand, if all or most of the output is going to change in response to a single variable changing its value, then it is probably best to wrap Dynamic around the whole thing.

Dynamic in Options

Dynamic can be used on the right-hand side of options, in those cases where the option value will be transmitted to the front end before being used. This is a somewhat subtle distinction related to the discussion in "Where Should Dynamic Be Placed in an Expression?".

An option like PlotPoints in plotting commands cannot have Dynamic on the right-hand side, because the plotting command needs to know a specific numerical value before the plot can be generated. Remember that Dynamic has the effect of delaying evaluation until the expression reaches the front end, and in the case of PlotPoints, that is too late since the value is needed right away. On the other hand, options to functions that do their work in the front end can usually, and usefully, accept Dynamic in their option values.

For example, you can control the size of a block of text in two ways.

Dynamic can be wrapped around a whole Style expression.
In[10]:=
Click for copyable input
In[11]:=
Click for copyable input
Out[11]=
Or Dynamic can be only in the FontSize option value.
In[59]:=
Click for copyable input
Out[59]=

There are two potential advantages to putting the Dynamic in the option value. First, suppose the dynamically regenerated expression is very large, for example, the entire document. It is inefficient to retransmit it from the kernel to the front end every time the font size is changed, as is necessary if Dynamic encloses the whole expression.

Second, the output of a Dynamic expression is not editable (since it is liable to be regenerated at any moment), which makes the output of the first example noneditable. But the text in the second example can be edited freely since it is ordinary static output: only the option value is dynamic.

Dynamic option values can be also set in the Option Inspector. They are allowed at the cell, notebook, or global level, and in stylesheets. (Note, however, that if you set a dynamic option value in a position where the value will be inherited by many cells, for example in a stylesheet, there can be a significant impact on performance.)

You can set dynamic option values through SetOptions, as well.
In[51]:=
Click for copyable input
In[51]:=
Click for copyable input
Having linked the background color of the notebook to the global variable x, it can now be controlled by a slider or by a program.
In[52]:=
Click for copyable input
Out[52]=
Of course, it is good to be able to return to normal.
In[53]:=
Click for copyable input

Dynamic and Infinite Loops

If you are not careful, you can easily throw Dynamic into an infinite loop.

This counts upward as fast as possible for as long as it remains on screen.
In[54]:=
Click for copyable input

This is not a bug (but delete the above output if it is distracting you to have it there).

Because the output is updated and the screen redrawn after each cycle of an infinite loop, it is actually quite a useful thing to be able to do. Generally speaking, the system will remain responsive to typing, evaluation, and so on, even as the infinitely updating Dynamic zips along.

It is also useful to make such a selftriggering Dynamic that stops changing at some point.

This is a "droopy" slider that always drops back to zero no matter what you drag it to.
In[55]:=
Click for copyable input
Out[55]=

If you have a CPU monitor running, you will see that while the slider is dropping there is a small load on the CPU (for redrawing the screen, primarily), but once it reaches zero, the load drops to nothing. The dynamic tracking system has noticed that the value of x did not change: therefore, further updating is not necessary until someone changes the value of x again (e.g. when you click on the slider). "Advanced Dynamic Functionality" describes in more detail how the dynamic tracking system works.

A Good Trick to Know

Because it has the attribute HoldFirst, Dynamic does not evaluate its first argument. This is fundamental to the workings of Dynamic, but it can lead to a somewhat unexpected behavior.

For example, suppose you have a list of numbers you wish to be able to modify by creating one slider to control each value.

This creates the list and a dynamic display of its current value.
In[1]:=
Click for copyable input
In[2]:=
Click for copyable input
Out[2]=
This attempts to make a table of sliders, one for each element of the list, using to access the individual members.
In[3]:=
Click for copyable input

Surprisingly, this does not work! You can see an error indication around the sliders, they cannot be moved, and the dynamic output above never changes. You might even jump to the conclusion that part extraction syntax cannot be used in this way with controls. Nothing could be further from the truth.

The problem is that the variable i was given a temporary value by the Table command, but that value was never used, because Dynamic is HoldFirst.

Looking at the InputForm of the table of sliders reveals the problem.
In[59]:=
Click for copyable input
Out[59]//InputForm=

What is needed is to do a replacement of the variable i with its temporary value, even inside held expressions.

This can be done with /. or with the somewhat peculiar but convenient idiomatic form demonstrated here.
In[60]:=
Click for copyable input

This output shows that Dynamic does in fact work perfectly with part extraction syntax, a very useful property.

Slow Evaluations inside Dynamic

Dynamic wrapped around an expression that will take forever, or even more than just a few seconds, to finish evaluating is a bad thing.

If you evaluate this example, you will have to wait about five seconds before seeing the output $Aborted.
In[61]:=
Click for copyable input

During the wait for the Dynamic output to evaluate, the front end is frozen, and no typing or other action is possible. Because updating of ordinary dynamic output locks up the front end, it is important to restrict the expressions you put inside Dynamic to things that will evaluate relatively quickly (preferably, within a second or so). Fortunately computers, and the Wolfram System, are fast, so a wide range of functions, including complex 2D and 3D plots, can easily be evaluated in a fraction of a second.

To avoid locking up the front end for good, dynamic evaluations are internally wrapped in TimeConstrained, with a timeout value of, by default, five seconds. (This can be changed with the DynamicEvaluationTimeout option.) In certain extreme cases, TimeConstrained can fail to abort the calculation, in which case the front end will, a few seconds later, put up a dialog box allowing you to terminate dynamic updating until the offending output has been deleted.

Fortunately there is an alternative if you need to have something slow in a Dynamic. The option SynchronousUpdating->False allows the dynamic to be evaluated in a way that does not lock up the front end. During evaluation of such an asynchronous Dynamic, the front end continues operating as usual, but the main Shift+Enter evaluation queue is occupied evaluating the Dynamic, so further Shift+Enter evaluations will wait until the Dynamic finishes. (Normal synchronous Dynamic evaluations do not interfere with Shift+Enter evaluations.)

Evaluate this example, and you will see a gray placeholder rectangle for about 10 seconds, after which the result will be displayed.
In[62]:=
Click for copyable input
Out[62]=

Importantly, during that 10second pause you are free to continue working on other things in the front end.

"Advanced Dynamic Functionality" gives more details about the differences between synchronous and asynchronous dynamic evaluations. In general, you should not plan to use asynchronous ones unless it is absolutely necessary. They do not update as quickly, and can interact in a very surprising, though not technically incorrect, way with controls and other synchronous evaluations.

Further Reading

The implementation details behind Dynamic and DynamicModule are worth understanding if you plan to use complex constructions, particularly those involving nested Dynamic expressions. This is discussed in "Advanced Dynamic Functionality".