Manipulate Secrets Revealed

Everything you never knew you didn’t know about Manipulate

Lou D’Andria

Wolfram Research, Inc.

The ubiquitous Manipulate function will be used in most talks at this conference, and is the basis for such ventures as the Demonstrations Project and Mathematica Player. But just how well do you know the Manipulate function? In this talk, we will examine some of its lesser known features, ranging from those that are fully documented to those that are not documented at all. The goal of this talk is to empower you to become a Manipulate expert.

The basics

This talk will not focus on the basics:

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

Manipulate[x,{x,{True,False}}]

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

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

We'll assume you have used Manipulate, possibly extensively, and will focus on features which are less widely known.

Refresher

If you'd like study the basics of Manipulate, please see the two very fine Manipulate tutorials, as well as my introductory talk from a previous tech conference. Or come talk to me.

• Introduction to Manipulate

• Advanced Manipulate Functionality

• http://library.wolfram.com/infocenter/Conferences/6526/

Syntax: Using options in variable specs

If the specification for a particular Manipulate variable causes it to use a certain control, then you can pass options to that control as options to the variable spec. Recall:

With[{opts = Style[opts,Blue]},Style[Grid[{
{Style["Variable Specification", Bold], Style["Default Control Type", Bold]},
{{var,xmin,∞, opts}, Animator},
{{var, xmin, xmax, opts}, Manipulator},
{{var,xmin,xmax,Δx, opts},Manipulator},
{{var,{xmin,ymin},{xmax,ymax}, opts}, Slider2D},
{{var,{xmin,ymin},{xmax,ymax},{Δx,Δy}, opts}, Slider2D},
{{var,{True, False}, opts}, Checkbox},
{{var, list, opts}, "PopupMenu or SetterBar"},
{{var, color, opts}, ColorSlider},
{{var, other, opts}, InputField}
}, ItemSize -> {"Columns" -> {{Scaled[0.5]}}},Background-> {"Rows" -> {{White, GrayLevel[0.9]}}}, Dividers->{"ColumnsIndexed"->{2 -> True},"RowsIndexed"->{2 -> True}}], FontFamily->"Helvetica", TextAlignment -> Center]]

Example

For example, this Manipulate uses a Manipulator control for x.

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

ImageSize and ContinuousAction are Manipulator options, and so they can be included in x's variable spec.

Manipulate[x,{x,0,1, ImageSize -> Small, ContinuousAction -> False}]

Options can also be set to values which dynamically depend on other variables. Note that, like elsewhere in Manipulate, no explicit Dynamic is required.

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

Syntax: Locator options

Locator variables in Manipulate let you overlay an arbitrary number of thumbs on top of a graphic or other expression, which intercepts all mouse clicks on the content area.

Manipulate[Graphics[Line[pts],PlotRange->1],{{pts,{{-.6,-.2},{.5,.6}}},{-1,-1},{1,1},Locator}]

But this control does not literally use the Locator function internally. Rather, it uses LocatorPane.

That means that the options you can use in the variable specs are LocatorPane options, like Appearance and LocatorAutoCreate.

Manipulate[Graphics[Line[pts],PlotRange->1],{{pts,{-{.6,.2},{.5,.6}}},{-1,-1},{1,1},Locator,Appearance -> Style["●",24,Red], LocatorAutoCreate->True}]

Bonus

You can have lots of single locator variables, or you can have one multi-locator variable, but you can' t mix and match.

OK:

Manipulate[..., {pt1,{-1,-1},{1,1}, Locator}, {pt2, {-1,-1},{1,1},Locator}]

OK:

Manipulate[..., {{pts,{{0,0},{.1,.2}}},{-1,-1},{1,1}, Locator}]

Not OK:

Manipulate[..., {{pts,{{0,0},{.1,.2}}},{-1,-1},{1,1}, Locator},{pt2, {-1,-1},{1,1},Locator}]

Bonus

You can specify your own dynamic tracking function for locator variables.

Manipulate[Graphics[Line[{{0,0},pt}],PlotRange->1],{{pt,{1,1}},{-1,-1},{1,1},ControlType->Locator,Experimental`TrackingFunction:>((pt=-#)&)}]

Syntax: {u, func} and {u, domain, func}

Manipulate lets you specify custom controls and controls with custom dynamic tracking functions by using {u, func} or {u, domain, func}

func is a pure function used to produce the display of the control.

Manipulate[{x,y},{x,0,10,Slider[Dynamic[x,(x=#;y=(Sqrt[#]))&],#2]&},{y,0,(Sqrt[10])}]

Advanced tip

Variables specified using the {u, domain, func} syntax will even autorun properly, which is especially important if you are creating a Mainpulate for the Demonstrations Project.

Bonus

Two argument are passed to func by default:
• #1 refers to Dynamic[var] for the current variable var
• #2 refers to the domain specification for that variable, if one is given, wrapped in a list.

Syntax: Control[]

Any control specification can optionally be specified inside the wrapper Control.

These are equivalent:

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

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

But the real power of Control comes when it's used inside of annotations.

Syntax: Annotations and Grouping

You can interleave a few different kinds of elements among variable specifications. These are intended to annotate existing controls, but they can also be used to insert other controls, or other arbitrary content.

Style[Grid[Prepend[Transpose[Partition[Prepend[Sort[Prepend[Manipulate`Dump`$validOtherArgumentHeads,String]],Delimiter],13,13,{1,1},""]],{Style["Annotations",Bold],SpanFromLeft,SpanFromLeft}],ItemSize -> {"Columns" -> {{Scaled[0.3]}}},Background-> {"Rows" -> {{White,GrayLevel[0.9]}}}, Dividers->{Center,{False,True}}],FontFamily->"Helvetica", TextAlignment -> Center]

Annotation example

Manipulate[Graphics[{Gray,Rectangle[],Black,Rotate[Rectangle[],θ,center],Red,PointSize[0.03],Point[center]}, PlotRange->2, Axes->True],
"The rotation variable runs from 0 to 2π:",
{θ,0,2π, ControlType -> Animator, ImageSize -> Small},
Delimiter,
"Rotation happens around whatever center the user specifies",
{{center,{0,0}},{0,0},{1,1}, ControlType -> Slider2D},
ControlPlacement -> Left
]

Control layout example

You can use this for arbitrary layout in the control area.

Manipulate[{x,y},Row[{
Control[{x,{1,2,3}}],Control[{y,{1,2,3}}]},Spacer[20]]]

Another layout example

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]]

Syntax: Annotation Placement

To change the placement of controls, you can use ControlPlacement as an option in the parameter spec.

Manipulate[Plot[f[x],{x,0,10}],{f,{Sin,Cos,Tan},ControlPlacement -> Left}]

To change the placement of annotations, use Item[expr, ControlPlacement -> place].

Manipulate[Plot[f[x],{x,0,10}],
{f,{Sin,Cos,Tan}},
Item[Row[{"Plot of the ", Dynamic[f], " function"}],ControlPlacement -> Bottom]]

Options: Initialization vs SaveDefinitions

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.

Of course, you can specify both Initialization and SaveDefinitions -> True. The automatically added code will be appended to your literal init code.

Be careful when using this with package functions -- especially functions with the ReadProtected attribute -- you may want to use a manually crafted Initialization option instead.

SaveDefinitions

h[x_]:=x^2

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

Initialization

Quiet[Needs["Graphics`Polyhedra`"];Needs["Graphics`Shapes`"];]

Manipulate[
ShrinkPolygons[OpenTruncate[Stellate[Polyhedron[shape],stellate],truncate],shrink],
{shape,Polyhedra},
{{stellate,1},0.1,2},
{{truncate,0},0,0.5},
{{shrink,1},0.1,2},
ControlPlacement->Bottom, TrackedSymbols -> "Local",Initialization :> (Needs["Graphics`Polyhedra`"];Needs["Graphics`Shapes`"]; // Quiet)]

Options: Avoiding $Aborted

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

SynchronousInitialization

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

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

SynchronousUpdating

If evaluating the first argument might take longer than that during interactive manipulation, set SynchronousUpdating -> False and possibly ContinuousAction -> False. (You should also think hard about whether such an example belongs in Manipulate to begin with.

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

Bonus

The default value of SynchronousUpdating is not True or False, but Automatic, so that ControlActive can work.

Manipulate[Plot3D[Sin[n x y],{x,0,3},{y,0,3}],{n,1,5}]

?PerformanceGoal

?ControlActive

Manipulate[ControlActive[x,(Pause[10];{x})],{x,0,1}]

Options: AutorunSequencing

AutorunSequencing is one of the most overlooked options, since it controls one of the most obscure but important features of Manipulate: Autorun.

Manipulate[{x,y,z},{x,0,1},{y,Checkbox},{z,Range[5]}]

Manipulate[{x,y,z},{x,0,1},{y,Checkbox},{z,Range[5]},AutorunSequencing -> {1,3}]

Note

Autorun is the same animation which is used when you export a Manipulate to a movie format like Flash, or when you upload a Demonstration.

To keep swf file size down, you can exclude controls via AutorunSequencing.

If you're unhappy with the Autorun animation, you can use bookmarks instead (next slide please)

Bonus: Autorun animation data

What if you don't just want to see the Autorun animation, but you want to get your hands on the parametrization used.

Bonus

m=Manipulate[{x,y},{x,0,1},{y,0,1},AutorunSequencing -> All];

{vars,funcs,{min,max},other}=Manipulate`AnimationData[m]

Block[{x},Plot[Evaluate[Through[funcs[x]]],{x,min,30}]]

Manipulate[Block[{x},Graphics[Line[Table[Through[funcs[x]],{x,min,t,0.01}]],PlotRange->{{0,1},{0,1}}]],{t,min,100}]

Options: Pre-defining bookmarks

Bookmarks are useful to set interactively, but they can also be specified in your input.

Manipulate[x,{x,0,1}, Bookmarks -> {"bottom" :> (x=0.2), "top" :> (x = 0.75), "mid" :> (x=.5)}]

Bonus

When two or more bookmarks are present, flash export and demonstrations animation will use them as animation key frames instead of Autorun.

The smoothness through which bookmarks are animated is specified by Manipulate's InterpolationOrder option.

InterpolationOrder -> 0 will effectively give a slideshow.

InterpolationOrder -> None will traverse a Manhattan-style route from one key frame to the next.

Options: LocalizeVariables

The LocalizeVariables option determines whether the variables you declare in your Manipulate input are automatically added to a DynamicModule or not.

Turning this off might be useful if you want to build your own interface, using Manipulate as a control layout engine.

Example

Note the use of None in the first argument to Manipulate, which suppresses the content area.

Manipulate[None,{xx,0,1},{yy,0,1},{zz,0,1},LocalizeVariables->False,Paneled -> False,AppearanceElements -> False,ImageMargins -> 10]//CreatePalette

Dynamic[{xx,yy,zz}]

Options: ControllerPath

The ControllerPath option will let you use the orientation sensor built into this computer, or any other HID system that might be excluded by default (like keyboards, trackpads, digitizers, …).

ControllerInformation[]

Example

Note that with the default value of ControllerLinking, the output of Manipulate must be selected before it responds to controllers.

Manipulate[Graphics[{Circle[{0,0},.2],Disk[{-x,-z},0.2],Opacity[0.4],Red,Disk[{-x,0}],Blue,Disk[{0,-z}]},PlotRange->3],{x,-2,2},{y,-2,2},{z,-2,2},ControllerPath->"Sudden Motion Sensor",ControllerMethod->"Absolute", SynchronousUpdating -> True]

Conclusion

Manipulate at first glance is rather analogous to Table, making it trivial to create useful interfaces in a few lines of code. But there is quite a bit of depth too. We've seen some of it today.

Questions?