Skip to main content

Manipulate

Wolfram Kernel
Execution environment
Manipulate[expr_, {u_Symbol, min_, max_}..]
Manipulate[expr_, {{u_Symbol, initial_}, min_, max_}..]
Manipulate[expr_, {{u_Symbol, initial_}, min_, max_, step_}..]
Manipulate[expr_, {{u_Symbol, initial_, label_String}, min_, max_, step_}..]

generates a version of expr with controls added to allow interactive reevaluation

Manipulate[expr_, {{u_Symbol}, values_List}..]
Manipulate[expr_, {{u_Symbol, initial_}, values_List}..]
Manipulate[expr_, {{u_Symbol, initial_, label_String}, values_List}..]

Manipulate can be used on any valid Wolfram Expression. 2D/3D plots and images passed as expr or part of it will be automatically optimized using Just-in-Time (JIT) transpiler if possible. This provides an immediate mode for a user to construct dynamic interactive widgets.

note

By its nature all interactivity in WLJS Notebooks are implemented in retained mode, while Manipulate is a wrapper over low-level building blocks such as Offload, InputRange and etc with a diff algorithm used to optimize evaluation of changes.

tip

For frequently changing data or complex visuals we still do recommend to use low-level building blocks.

Use ManipulatePlot and ManipulateParametricPlot for basic plots.

Examples

Here is a basic example involving symbolics:

Manipulate[Series[Sinc[x], {x, 0, n}], {n, 1, 5, 1}]

Here is a few examples with Plot expression, which effectively use JIT:

Manipulate[
Plot[Sin[a x + b], {x, 0, 6}], {{a, 2, "Multiplier"}, 1,
4}, {{b, 0, "Phase Parameter"}, 0, 10}, ContinuousAction->True]

Manipulate[Plot[1.0 + Sin[w] Sin[x + w],{x,0,5Pi}, Epilog->{
Red, Point[{8.0, 1.0 + Sin[w] Sin[8.0 + w]}]
}], {w,0,Pi}, ContinuousAction->True]

Another example, that solves ODE on-fly:

Manipulate[
Plot[Evaluate[
y[t] /. First[
NDSolve[ {y''[x] == -x y[x], y[0] == a, y'[0] == b},
y, {x, 0, 4}]]], {t, 0, 4},
Epilog -> {Point[{4, 1/2}], Green, Arrow[{{0, a}, {1, b + a}}], Red,
Point[{0, a}]}, PlotRange -> 3],
{{a, 1}, -3, 3},
{{b, 0}, -3, 3}]

3D plot example:

Manipulate[Plot3D[Sin[n x] Cos[n y], {x,-1,1}, {y,-1,1}], {n, 1, 5, 0.3}, ContinuousAction->True]

Images:

img = ImageResize[ExampleData[ExampleData["TestImage"] // Last], 350];
Manipulate[
ImageAdjust[img, {c,a}],

{{c, 0},0,5,0.1},
{{a, 0},0,5,0.1},
ContinuousAction->True
]

Here is an example with mixed symbolics and graphics:

JIT Transpiler

Manipulate as well as Animate uses a diff algorithm that detects and tries to convert manipulated expressions to a more optimized dynamic ones using a low-level Offload technique.

If something else goes wrong, it will deoptimize it back and send an original expression to the output.

Our transpiler does not cover all symbols and is limited to the following for now:

  • Line, Point, Polygon, Tube, Arrow, Disk, Circle, Sphere, Cuboid, Rectangle, Text
  • GraphicsComplex in the context of Graphics3D
  • Image
  • PlotLabel in the context of Graphics
  • LineLegend, PointLegend, SwatchLegend

which is a good subset to cover the output produced by Plot, Plot3D and many others standard functions. What will not be supported in the near future:

  • PlotRange mutations are ignored
  • adding/removing Line, Point and etc primitives at runtime leads to deoptimization
  • changing color or opacity leads to deoptimization

Tips for better performance

If you still want to use Manipulate on some complex expressions, there are some tricks to avoid deoptimization of JIT engine

tip
  • Try to keep the number of curves/traces/polygons expressions the same if possible. Try not to add new entities to your graphs.
  • PerformanceGoal->"Speed" is also a good option for 3D plots.
  • Mesh->None might also help.
  • PlotRange->Full can help to avoid fragmentation of line segments
  • Avoid changing colors, opacity at runtime
note

In any case you can still animate anything with a great performance using low-level building blocks Offload and AnimationFrameListener.

See Advanced section of the documentation

Debugging

To see the latest message of JIT failure - evaluate the symbol:

CoffeeLiqueur`Extensions`Manipulate`Diff`$lastJITFailure

Portability

The same as for Animate. Manipulate widgets can be exported to Interactive HTML or MDX in automatic mode.

warning

Please keep the number of possible state determined by all your sliders and selection boxes below 500-600.

Options

"UpdateFunction"

Allows to alter the expression, prevent default actions or cause side-effects upon update. The following return values are expected

Function[input,
(* side effects *)
(* RETURN *)
True <- accept change
False <- prevent default
_String <- will be written instead
]

One can completely bypass the default reevaluation and use side-effects only

Module[{r},
Manipulate[Graphics[Disk[{0,0}, r//Offload]],
{{radius, 1}, 0,1},
"UpdateFunction" -> Function[value,
r = value;
False (* always reject *)
]
]
]

However, we do recommend to use InputRange directly instead of Manipulate for such cases.

ContinuousAction

By the default is False, which means that any update happens after users action, but not before.

"ControlsLayout"

By the default is "Vertical", another possible value is "Horisontal"

PerformanceGoal

By the default is "Speed", which involves JIT Transpiler. Change it to any other value to disable it completely

"JITFeature"

By the default is True, which involves JIT Transpiler. If either of PerformanceGoal or "JITFeature" is set no a non-default value JIT transpiler will be disabled.

Appearance

By the default is "Default". Set it to None to remove the frame and info boxes.

MMAView

MMAView wrapper allows to use native Wolfram Engine rendering engine for manipulate expressions, any expression. It uses a parallel kernel to rasterize the provided expression and stream updates to the frontend.

Manipulate[Plot3D[Sin[n x] Cos[n y], {x,-1,1}, {y,-1,1}], {n, 1, 5, 1}] // MMAView

Try to drag and rotate the plot We automatically detect if the manipulate expression is [[Graphics3D]] and if so, we provide additional mouse controls.

warning

It literally streams uncompressed raster images in real-time. Please do not overuse it, and try to use WLJS dynamics in general if possible.

Supported output forms