Skip to main content

Dynamics and User's Input

This is one of the major feature developed in WLJS Notebook

Download original notebook

A shortcut

If you just need to plot a function with a few parameters to vary

ManipulatePlot[Sum[Sin[i ω t], {i, 10}], {t,0,2Pi}, {ω, 0., 10.1, 0.1}]

Or for multiple function

ManipulatePlot[{Sin[ω t], Sum[Sin[i ω t], {i, 10}]}, {t,0,2Pi}, {ω, 0., 10.1, 0.1}]

Or for animating

AnimatePlot[{Sin[ω u], Sum[Sin[i ω u], {i, 10}]}, {u,0,2Pi}, {ω, 0., 5.1, 0.1}]
(*VB[*)(FrontEndRef["a83bbcae-9605-49c1-ad4f-0d55a9e7e1b0"])(*,*)(*"1:eJxTTMoPSmNkYGAoZgESHvk5KRCeEJBwK8rPK3HNS3GtSE0uLUlMykkNVgEKJ1oYJyUlJ6bqWpoZmOqaWCYb6iammKTpGqSYmiZappqnGiYZAACRBhYs"*)(*]VB*)

Or for general purpose

Manipulate[Plot3D[Sin[n x] Cos[n y], {x,-Pi,Pi}, {y,-Pi,Pi}], {n, 1,3,1}]

For whom need a deeper look

Sliders and data

The simples way to demonstarate it is to generate some data

generate[ω_, t_] := Sum[Sin[i ω t], {i, 10}]
Plot[generate[10., t], {t, 0, 2Pi}]
(*VB[*)(FrontEndRef["e2ac9276-93fa-47c8-8225-9fa8c7f20617"])(*,*)(*"1:eJxTTMoPSmNkYGAoZgESHvk5KRCeEJBwK8rPK3HNS3GtSE0uLUlMykkNVgEKpxolJlsamZvpWhqnJeqamCdb6FoYGZnqWqYlWiSbpxkZmBmaAwCDpRVY"*)(*]VB*)

This is a static picture, but we can make it dynamic. The major drawback is that we have to use basic primitives such as Line and Graphics wrapper for this to happen

Primitives

Let's try it out with Graphics step by step

dyn = Table[{t, generate[10., t]}, {t, 0, 2Pi, 0.04}];
Graphics[Line[dyn]]
(*VB[*)(FrontEndRef["cdb634ad-91f7-4a79-8d3e-32f8b7258708"])(*,*)(*"1:eJxTTMoPSmNkYGAoZgESHvk5KRCeEJBwK8rPK3HNS3GtSE0uLUlMykkNVgEKJ6ckmRmbJKboWhqmmeuaJJpb6lqkGKfqGhulWSSZG5lamBtYAACMhxWI"*)(*]VB*)

A bit more clarity

Graphics[Line[dyn], Axes->True, PlotRange->{{0,6}, {-7,7}}]
(*VB[*)(FrontEndRef["ea1e5a0c-b365-446e-a8dc-bbe08c0f96f6"])(*,*)(*"1:eJxTTMoPSmNkYGAoZgESHvk5KRCeEJBwK8rPK3HNS3GtSE0uLUlMykkNVgEKpyYappomGiTrJhmbmeqamJil6iZapAC5SakGFskGaZZmaWYAktcWYA=="*)(*]VB*)

However, this is still a static picture, to make it dynamic, we need to use Offload keyword

Graphics[Line[dyn // Offload], Axes->True, PlotRange->{{0,6}, {-7,7}}]
(*VB[*)(FrontEndRef["f2c5929e-c921-4106-917b-1c74a3b074fd"])(*,*)(*"1:eJxTTMoPSmNkYGAoZgESHvk5KRCeEJBwK8rPK3HNS3GtSE0uLUlMykkNVgEKpxklm1oaWabqJlsaGeqaGBqY6VoamifpGiabmyQaJxmYm6SlAAB7XBVD"*)(*]VB*)

Note: Line, Rectangle, Disk, Circle, Sphere, and other primitives support Offload. You cannot put an arbitary expression into Offload

Now try to evaluate this cell

dyn = Table[{t, generate[3., t]}, {t, 0, 2Pi, 0.04}];

The graph above should be updated automatically, since the dynamic link between Line and dyn symbols is created.

Adding sliders

Of course we need element for a user to interact with

slider = InputRange[0, 10, 1, "Label"->"Frequency"];
slider
(*VB[*)(EventObject[<|"Id" -> "a613de31-6810-4712-a709-c1954e17a01a", "Initial" -> 5, "View" -> "f35d9e88-9ed4-4119-9f79-14a93457c684"|>])(*,*)(*"1:eJxTTMoPSmNkYGAoZgESHvk5KRCeEJBwK8rPK3HNS3GtSE0uLUlMykkNVgEKpxmbplimWljoWqammOiaGBpa6lqmmVvqGpokWhqbmJonm1mYAACAnRUO"*)(*]VB*)

In order to read the input, we need to assign a handler function. Let it be this one

EventHandler[slider, Function[freq, 
  dyn = Table[{t, generate[freq, t]}, {t, 0, 2Pi, 0.04}];
]];

Note: by dragging a slider above, our dynamic plot should be updated

Wrapping up

It is better not to litter the global scope and use Module or LeakyModule to scope our variables

generate[ω_, t_] := Sum[Sin[i ω t], {i, 10}];

LeakyModule[{data, slider},
  slider = InputRange[0, 10, 1, "Label"->"Frequency"];
  EventHandler[slider, Function[freq,
    data = Table[{t, generate[freq, t]}, {t, 0, 2Pi, 0.04}];
  ]];

  slider // EventFire; (* just to initialize *)

  {
    Graphics[{ColorData[97][2], Line[data // Offload]}, Axes->True, PlotRange->{{0,6}, {-7,7}}],
    slider
  } // Row 
]
(*GB[*){{(*VB[*)(FrontEndRef["bf57a6c2-24ca-45c7-a5be-4fa92bd1d8f6"])(*,*)(*"1:eJxTTMoPSmNkYGAoZgESHvk5KRCeEJBwK8rPK3HNS3GtSE0uLUlMykkNVgEKJ6WZmieaJRvpGpkkJ+qamCab6yaaJqXqmqQlWholpRimWKSZAQCQzxZi"*)(*]VB*)(*|*),(*|*)(*VB[*)(EventObject[<|"Id" -> "1f013588-a60b-4b42-a6fd-fa6a85996415", "Initial" -> 5, "View" -> "ccb79ad0-7d52-45e8-adc3-6856c779f875"|>])(*,*)(*"1:eJxTTMoPSmNkYGAoZgESHvk5KRCeEJBwK8rPK3HNS3GtSE0uLUlMykkNVgEKJycnmVsmphjomqeYGumamKZa6CamJBvrmlmYmiWbm1umWZibAgCPBRXA"*)(*]VB*)}}(*]GB*)

try to drag a slider