Dynamics and User's Input
This is one of the major feature developed in WLJS Notebook
Download original notebookA 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