Beyond “Got Manipulate”

Paul Wellin
wellin@wolfram.com

Overview

With the introduction of Manipulate in Mathematica 6, quick and easy dynamic interface construction was at everyone’s fingertips. Perhaps you have dabbled a bit with Manipulate. This talk will take you beyond the basics and demonstrate some of the less-known/used features. We will cover:

introduction to Manipulate

controls: control type, parameter list syntax, Control

annotations

options

building blocks

If you can make a Table,…

If you know how to create a Table in Mathematica, then you know how to use Manipulate.

Table[(n^2),{n,1,100,1}]

Manipulate[(n^2),{n,1,100,1}]

Table creates static output (in a list); Manipulate creates dynamic output.

Scope of Manipulate

Anything that you can operate on in Mathematica can be operated on with Manipulate. Really, anything!

Expressions

Display some of the new Graph objects.

Manipulate[
Row[Table[graph[i,2],{i,3,7}]],
{graph,{CirculantGraph,DeBruijnGraph,KnightTourGraph,PetersenGraph,TuranGraph,CompleteKaryTree},ControlType->PopupMenu}]

Find all those plotting functions that have a specific option.

Manipulate[
Select[ToExpression[funs],MemberQ[Options[#],opt,Infinity]&],
{{opt,DataRange,"Option"},opts},
Initialization:>{
funs = Names["System`*Plot*"];
opts=Union@Map[First,Union@Flatten[Map[Options,ToExpression@funs]]]
}]

Data

Systematically explore country data by continent.

Manipulate[
Grid[Prepend[Outer[CountryData[#1,#2]&,CountryData[continent],{"Name","Area","Population"}],{"Country","Area","Population"}],
Alignment->Left,BaseStyle->{FontFamily->"Helvetica"},Frame->All,Background->{None,{LightBlue,{LightYellow}}}],
{{continent,"SouthAmerica","Continent"},DeleteCases[CountryData["Continents"],"Antarctica"]}]

Graphics

Manipulate indirectly through controls (e.g., sliders, color setters):

Manipulate[
Plot[Sin[n x],{x,0,2π},PlotStyle->{Thick,color}],
{n,1,10},{color,Purple}
]

Or manipulate directly via locators:

Manipulate[
Show[
Graphics[{{Point[p],Thick,Red,Line[p]}}],
ParametricPlot[BSplineFunction[p][t],{t,0,1}]],
{{p,controlpts},Locator},
Initialization:>{controlpts={{1,5},{2,3},{3,2},{4,5},{5,4},{6,4},{7,3}}}]

Images

Edge detection, manipulating the scale of the pixel range.

Manipulate[EdgeDetect[,r],
{r,0.5,15}]

Notebooks

Notebooks are just (symbolic) expressions so we can manipulate them as well.

nb=CreateDocument[{
Cell["Notebook Title","Title"],
Cell["Section 1.1","Section"],
Cell["This is a text cell","Text"]
},Magnification->1.5]

Manipulate[
SetOptions[nb,Background->Hue[val],WindowOpacity->op];
Column@{Row[{ColorSetter@Hue[val],"  ",Hue[val]}],StringForm["Background opacity = `1`",op]},
{val,0,1},{op,1,0}]

Basic Controls

The basic syntax for Manipulate is:

Manipulate[body, parameter_specs, options]

With a slightly different syntax for the parameter list, Manipulate will use different control elements in the output. Alternately, you can explicitly set the ControlType.

Setter bars: use {parameter,{(Subscript[val, 1]),(Subscript[val, 2]),…,(Subscript[val, n])}}.

Manipulate[
Plot[f[x],{x,0,2π}],
{f,{Sin,Cos,Tan}}]

Explicitly set the controller.

Manipulate[
Plot[f[x],{x,0,2π}],
{f,{Sin,Cos,Tan},ControlType->PopupMenu}]

DynamicModule[{pua,rbba,cbba,tgba},Grid[{
{Style["Control type",FontWeight->"Bold"],Style["Examples",FontWeight->"Bold"]},
{"Slider",Manipulate[x,{x,0,1,ControlType->Slider},LabelStyle->16]},
{"2DSlider",Manipulate[x,{x,0,1,ControlType->Slider2D},LabelStyle->16]},
{"PopupMenu",Row[{PopupMenu[Dynamic[pua],{a,b,c,d}],"       ",InputField[Dynamic[pua],FieldSize-> 5]}]},
{"RadioButtonBar",Row[{RadioButtonBar[Dynamic[rbba],Range[5]],"       ",InputField[Dynamic[rbba],FieldSize-> 5]}]},
{"CheckBoxBar",Row[{CheckboxBar[Dynamic[cbba],{1,2,3}],"       ",InputField[Dynamic[cbba],FieldSize-> 5]}]},
{"TogglerBar",Row[{TogglerBar[Dynamic[tgba],Range[5]],"       ",InputField[Dynamic[tgba],FieldSize-> 7]}]},
{"InputField",Manipulate[input,{input,3.14},ControlType->InputField,LabelStyle->16]},
{"ColorSlider",ColorSlider[Pink]}
},BaseStyle->{"TraditionalForm",FontFamily->"Helvetica"},Alignment->{Left},Background->LightYellow,Frame->All,Spacings->{2,0.62}]]

For a complete list, see the guide page on Control Objects.

Other Controls

The documentation for Manipulate has numerous examples showing the various controls that you can use. Below are just two, TogglerBar and Locator.

Manipulate[
DisplayCityWeather[cities],
{{cities,{"New York","Champaign"},"Current temp in:"},{"New York","Champaign","Tokyo","Paris","Bangkok","Mumbai"},ControlType->TogglerBar}]

Locator variables let you overlay objects on top of a graphic (or other expression); they intercept all mouse clicks in the content area.

A static graphic:

With[{pts={{0,0},{1,0},{0,1}}},
Graphics[{Pink,Polygon[pts]}]
]

A dynamic graphic:

Manipulate[
Graphics[{Pink,Polygon[pts]},PlotRange->1.1],
{{pts,{{0,0},{1,0},{0,1}}},Locator}]

This control is actually using LocatorPane internally; hence, the options you can use in the variable specs are LocatorPane options, like Appearance and LocatorAutoCreate.

Manipulate[
Graphics[{Pink,Polygon[pts]},PlotRange->1.1],
{{pts,{{0,0},{1,0},{0,1}}},Locator,LocatorAutoCreate->True}]

Control

You can use the Control wrapper to explicitly specify your variables. So, for example, these are equivalent:

Manipulate[x,{x,0,1}]

Manipulate[x,Control[{x,0,1}]]

But Control also gives you greater control over placement and other aspects of your interface.

Side-by-side vertical sliders positioned on the left:

Manipulate[Plot[a Cos[b (t-c)],{t,0,2 π},PlotRange->12],

Grid[{{"amp","freq","phase"},

{Control[{{a,3,Null},1,12,ControlType-> VerticalSlider}],Control[{{b,3,Null},1,12,ControlType-> VerticalSlider}],Control[{{c,3,Null},1,12,ControlType-> VerticalSlider}]}}],

ControlPlacement-> Left]

You can use this for arbitrary layout in the control area (which is one of the current limitations of the simpler Manipulate syntaxes).

Manipulate[{(x^2),(y^3)},
Row[{
Control[{x,{1,2,3}}],
Spacer[40],
Control[{y,{a,b,c}}]
}]]

Here is a more involved example using annotation and a more complicated layout:

Manipulate[Plot[amp f[freq x],{x,0,6},PlotStyle->{color,Dashing[dashing],Thickness[thickness]},Axes->axes,Frame->frame,AxesOrigin->axesorigin,PlotLabel->f],
{f,{Sin,Cos,Tan}},
TabView[{
"Function Variations" -> Column[{Control[{freq,1,5}],Control[{amp,1,5}]}],"Axes and Frames" -> Column[{Control[{axes,{True,False}}],Control[{frame,{False,True}}],Control[{axesorigin,{0,0},{6,1}}]}],
"Plot Style" -> Column[{Control[{color,Blue}],Control[{dashing,0,0.1}],Control[{thickness,0.001,0.1}]}]}, ImageSize -> Automatic]]

Options

Options for variable specifications can also be given as options to Manipulate as a whole. Manipulate also has other options. We’ll look at several useful options.

Options[Manipulate]

You can use the Initialization option to Manipulate to specify some code that gets evaluated when the Manipulate output is first displayed, for instance in a new Mathematica session.

SaveDefinitions uses FullDefinition to extract the kernel definitions for all the symbols involved in your Manipulate, and stores them in the Initialization option.

You can think of SaveDefinitions as the automatic version of Initialization.

h[x_]:=x^2

Manipulate[h[x],{x,0,1},SaveDefinitions->True]

The above is effectively equivalent to this:

Manipulate[h[x],{x,0,1},Initialization:>{h[x_]:=(x^2)}]

By default Manipulate tracks all variables that are explicitly present in its first argument.

Manipulate[{x,y},{x,0,1}]

Slider[Dynamic[y]]

The TrackedSymbols option allows you to hint the dynamic tracking mechanism, only watching variables that you care about.

Manipulate[{x,y},{x,0,1},TrackedSymbols:>{x}]

Dynamic evaluations are only allowed to take a few seconds by default.

If evaluating the Initialization might take longer than that, set SynchronousInitialization -> False.

If evaluating the first argument might take longer than that during interactive manipulation, set SynchronousUpdating -> False.

Manipulate[x,{x,0,1},Initialization:>Pause[7], SynchronousInitialization->False]

Manipulate[Pause[x];x,{x,0,7,ContinuousAction -> False}, SynchronousUpdating->False]

There are several ways to use Manipulate to generate animations.

Use the animation controls provided by the default control types.

Use the Animate function (which actually creates a Manipulate with particular settings).

Use the built-in autorun animation, which will explore the Manipulate’s computational space either one variable at a time, or all at once. (This is used by flash export and the Demonstrations site.)

Use the built-in bookmarking capabilities, which can automatically animate between these as key frames.

Animate[Plot[a Cos[b (t-c)],{t,0,2 π},PlotRange->{-12,12}],
{a,1,12},{b,1,12},{c,1,12}]

Manipulate[Plot[a Cos[b (t-c)],{t,0,2 π},PlotRange->{-12,12}],
{a,1,12},{b,1,12},{c,1,12},
ControlType->Animator]

Building Blocks

Manipulate is a highly-structured dynamic interface. But it is only one possibility. You can use the primitive building blocks to build your own structures.

Dynamic gives output that is automatically updated to always reflect its current value.

x=10;

(x^2)

Dynamic[(x^2)]

x=5

The first argument to slider is the position; an optional second argument specifies the range and step size. Default range from 0 to 1.

{Slider[Dynamic[x]],Dynamic[x]}

DynamicModule has a similar syntax to Module and is used to localize and initialize variables. A key difference is that DynamicModule works in the front end while Module is a kernel function. The many implications for this are discussed in the tutorials Introduction to Dynamic and Advanced Dynamic Functionality.

Panel[DynamicModule[{x},Column[{
Slider[Dynamic[x]],
Item[Dynamic[x],Background->White,Frame->All,FrameStyle->LightGray]
}]]]

This panel displays all those functions with a given option (FunctionsWithOption is defined at the end of this notebook).

Panel[DynamicModule[{opt=MaxRecursion},
Column[{
InputField[Dynamic[opt]],
Dynamic[FunctionsWithOption[opt]]
}]
]]

As an aside, many dynamic constructs play nice with Style:

Panel[DynamicModule[{opt=MaxRecursion},
Column[{
Style[InputField[Dynamic[opt]],16],
Style[Dynamic[FunctionsWithOption[opt]],16]
}]],
Style["Functions with the option: ",Purple,18]]

Other Resources

Manipulate tutorial

Advanced Manipulate Functionality tutorial

Introduction to Dynamic tutorial

Advanced Dynamic Functionality tutorial

demonstrations.wolfram.com

Initialization

FunctionsWithOption[opt_Symbol]:=Quiet@Select[Names["System`*"],MemberQ[ToExpression["Options[Unevaluated["<>#<>"]]"],opt,{2}]&]

SetOptions[ParametricPlot,PlotStyle->Thick];

<<Units`

DisplayCityWeather[lis_List]:=With[{cities=lis},
Grid[Join[{{
Style["City",FontWeight->"Bold"],Style["Temp (°C)",FontWeight->"Bold"],Style["Temp (°F)",FontWeight->"Bold"]}},
Map[{#,WeatherData[#,"Temperature"],ConvertTemperature[WeatherData[#,"Temperature"],Centigrade,Fahrenheit]}&,cities]],
Frame->All,Background->LightYellow,Alignment->{{Left,Right,Right},Automatic},BaseStyle->{FontFamily->"Helvetica"}]]

$Line=0;