Making interactive models

Manipulate[...]

Using the command Manipulate[...] we can turn a static computation or graph into a dynamic and sophisticated model. We can wrap Manipulate[...] around any Wolfram command to create an interactive model. We need to introduce a parameter that we want to manipulate and some bounds for that parameter.

Parameter ranges are given inside curly brackets: 
{x, 4, 7}   -- specifies an interval [4,7] that the parameter x belongs to.
{x, {4,7}} -- specifies a discrete set of values that x can take on.
{{x, 5, “Some text describing the meaning of the parameter x”}, 4,7}  -- x belongs to the interval [4,7] and the default value is 5

Help->Demonstrations gives you a list of pre-built Wolfram Demonstration Projects. They all use the command Manipulate[...]. You can browse by topic and see the available templates. You can then download the project as a .cdf, which means that you get an interactive version that you can run locally on your computer, or you can download the author code, which means that you get a notebook (.nb) with the necessary code to generate the model.

An Interactive Model

Example 1. Make an interactive model that computes n^2, for n in the interval [1,4].

Solution 1

Manipulate[n^2, {n,1,4}]

If you click the plus sign at the end of the slider, you get a set of video controls. You can introduce a particular value of the parameter and hit Enter to jump to that value. When you do a presentation, you can also hide the Wolfram commands and show only the interactive model. Once an interactive model is created, you can copy and run the model in a new notebook. You do not need to copy the code, only the model.

We can also set a default value for n when we call Manipulate[..]. The example below assumes that n=3 is the default value.

Manipulate[n^2, {{n,3},1,4}]

We can indicate the domain of n in different ways!

We can indicate the domain of n in different ways (each way will generate a different type of control button, slider, popup menu, checkbox, etc.)

In the two examples below, n takes values between 1 and 4 in steps of 0.25 and respectively in steps of 1. The Manipulate command creates a slider.

Manipulate[n^2, {n,1,4,0.25}]

Manipulate[n^2, {n,1,4,1}]

Instead of incrementing n in steps of 1, we can enumerate the list of possible values for n. The Manipulate command will create a button for each possible value.

Manipulate[n^2, {n,{1,2,3,4}}]

If the list of possible values for n is too large, then a drop - down list will be created.

Manipulate[n^2, {n,{1,2,3,4,5,6,7,8,9}}]

If no interval for n is given, Manipulate will create an empty text box where you can type in the value for n, then click Enter to obtain the result .

Manipulate[n^2, {n}]

Options for the controls can also be given within the specification for the variables.

The option setting ControlType→type attempts to use controls of the specified type. Possible control types include: Animator, Checkbox, CheckboxBar, ColorSetter, ColorSlider, InputField, Manipulator, PopupMenu, RadioButton or RadioButtonBar, Setter or SetterBar, Slider, Slider2D, TogglerBar, Trigger, and VerticalSlider, None. More information can be found in the Mathematica Documentation. 
The option setting ControlPlacement→pos specifies that controls should be placed at position pos relative to expr. Possible settings for position are Bottom, Left, Right, and Top.

Manipulate[n^2, {n,{1,2,3,4,5,6,7,8},ControlType->SetterBar}]

Manipulate[n^2, 
{n,{1,2,3,4,5,6,7,8},ControlType->PopupMenu, ControlPlacement->Left}
]

Manipulate[n^2, {n,{1,2,3,4,5,6,7,8},ControlType->VerticalSlider}]

Same Interactive Model, but different implementations

Example 1. Make an interactive model that computes n^2, for n in the interval [1,4].

Solution 2

Manipulate[
temp=n;
temp=temp^2;
temp,
{n,1,4}
]

Notice that the cell reevaluates itself continuously (the right cell bracket is constantly blinking), even when we do not change the position of the slider. You can confirm this by going to Evaluation->Find Currently Evaluating Cell. This happens because the variable temp has its value changed during the evaluation (temp =temp^2), even if the value of n has not changed.

Solution 3

The problem can be solved by making the global variable “temp” be local variable inside a Module. Nothing you do to local Module variables will cause reevaluating, because it is part of the definition of Module that values of local variables do not survive from one invocation to the next.

Manipulate[Module[{temp},
temp=n;
temp=temp^3;
temp],
{n,1,4}
]

Solution 4

Manipulate[
f[x_]:=x^2;
f[n],
{n,1,4}]

Solution 5

Manipulate[Module[{g},
g[x_]:=x^2;
g[n]],
{n,1,4}]

The function g is now a local variable, so it does not cause any extra reevaluations. Notice that it is not defined outside of Module[...], so if you try to call g[3] say, somewhere below, the function g will not be recognized.

g[3]

Solution 6

Manipulate[
f[x_]:=x^2;
f[n],
{n,1,4}, TrackedSymbols:>{n}]

We can keep the function f global, without causing any reevaluations of Manipulate, if we explicitly indicate that the only variable whose values we should keep track of is the parameter n (by default, Manipulate[...] tracks both f and n). The example above reevaluates only when n changes its value as a result of moving the slider.

Solution 7

h[x_]:=x^2
Manipulate[
h[n],
{n,1,4}]

We can also define the function h(x)=x^2 globally, before Manipulate[..]. At first glance, it looks like everything works well and without causing any reevaluations of Manipulate. 
The downfall is that the definition of the function h (which is called later in the body of Manipulate) is not saved together with the output of Manipulate. To see this, open a new Mathematica notebook, and set “Evaluation->Notebook’s Default Context” to “Unique to this notebook”. Then copy ONLY the output of Manipulate (that is, ONLY the interactive model, absolutely NO code) in the new notebook. Try changing the slider. What do you notice?

Solution 8

k[x_]:=x^2
Manipulate[
k[n],
{n,1,4},SaveDefinitions->True]

The option “SaveDefinitions->True” forces any function definitions used by Manipulate to be saved with the output. The output can be copied and directly run in a new notebook. Try it!

Working with random elements inside Manipulate

How about generating random elements inside the body of Manipulate[ ...]? Should the code below reevaluate itself as fast as possible, each time generating a new random integer?

Manipulate[
x =RandomInteger[n],
{n,{10,100}}
]

Every time you evaluate RandomReal[...] or RandomInteger[...] or RandomGraph[...], you get a different answer, and you might think that an assignment like x=RandomReal[...] inside Manipulate[...] should therefore constantly update itself as fast as possible. But this would normally not be useful, and would in fact have negative consequences for a number of algorithms that use randomness internally. For this reason, these functions are not "ticklish", in the sense that they do not trigger updates. If you want to see actually new random numbers, you have to use Refresh to specify how frequently you want the output updated.

Example 2. Make an interactive model that draws a random directed graph with n vertices, for n between 4 and 7.

Manipulate[
RandomGraph[{n,5},GraphStyle->"SmallNetwork", ImageSize->Medium], 
{n,{4,5,6,7}}]

If we do not want the graphics to rescale every time we generate a new graph, we can set the dimensions of the graphical object ImageSize -> {1000, 300}. Or we can set the dimensions of the window displayed by Manipulate[..] using ContentSize -> {1000, 300}.

Manipulate[
GraphPlot[Table[RandomInteger[],{n},{n}], VertexLabeling->True, DirectedEdges->True, ImageSize->{1000,300}], 
{n,4,7}]

Manipulate[
RandomGraph[{n,5},GraphStyle->"SmallNetwork", ImageSize->Medium], 
{n,{4,5,6,7}},
ContentSize->{1000,500}]

How to manipulate several functions of several parameters

Example 3. Make an interactive model that draws the graphs of the functions cos(mx) and sin(nx), where m is a continuous parameter in the interval [1,2], and n a discrete parameter in the set {4,5,6,7}.

Manipulate[
GraphicsRow[{
Plot[Cos[m*x],{x,0,2*Pi}],
Plot[Sin[n*x],{x,0,2*Pi}] }], 
{n,{4,5,6, 7}},
{m, 1,2}
]

It is possible to have correlated sliders.

Manipulate[
Column[{"Graphs of Cos(mx) and Sin(nx)",
Plot[Cos[m*x],{x,0,2*Pi}],
Plot[Sin[n*x],{x,0,2*Pi}] }], 
{n,m,2*m},
{m, 1,2}
]

Exercises:

Exercise 1. Make an interactive model that reads the value of two variables, total and sum, represented by two different controls, and outputs their sum, total+sum. Does the example below do that?

Manipulate[
 total=total+step;
{step,total},
{{total,0},-1000,1000,1},{{step,0},-10,10,1},
FrameLabel->"Good or bad?"]

Exercise 2. A way to compute the sum of the first m positive integers in Mathematica is to do a For loop, like the one written below. Turn the code below into an interactive model where m will be allowed to take any values in the set {10, 20, 30, 40, 50}.

m=5;
s=0;
For[i=1,i≤m,i++, s=s+i];
s

Exercise 3. Do an interactive model using Manipulate[...] that displays the pair of numbers x and ax^2+bx+c, where a,b,c are real parameters, and x is a randomly generated number, between min and max, x=RandomReal[{min,max}]. The model will have 5 controls that can be set by the user: a,b,c,min, max  (a, b, c are real numbers between 1 and 10, min is an integer number in the set {2,3,4}, and max is also an integer number in the set {5,6,7}).