bondscell_results$048f54ba-45d1-49e2-b19d-7ef634c77cf0queued¤logsrunning¦outputbody
mimetext/htmlrootassigneelast_run_timestampAڎQpersist_js_state·has_pluto_hook_features§cell_id$048f54ba-45d1-49e2-b19d-7ef634c77cf0depends_on_disabled_cells§runtime%smpublished_object_keysdepends_on_skipped_cells§errored$b1658a17-b59f-4c35-b7a0-1503e377c731queued¤logsrunning¦outputbody

The following cell automatically updates the content of the observable val_obs each time we move the slider. In turn, it updates the plot below.

mimetext/htmlrootassigneelast_run_timestampAڎzpersist_js_state·has_pluto_hook_features§cell_id$b1658a17-b59f-4c35-b7a0-1503e377c731depends_on_disabled_cells§runtime published_object_keysdepends_on_skipped_cells§errored$774f1c41-7a84-401a-950c-466cf05fcd92queued¤logsrunning¦outputbodyX

Warning

The code must be separated into four cells as above (slider, definition of the observable, update of the observable, plot). In fact, the definition of the observable could be included in the "plot cell".

mimetext/htmlrootassigneelast_run_timestampAڎzBppersist_js_state·has_pluto_hook_features§cell_id$774f1c41-7a84-401a-950c-466cf05fcd92depends_on_disabled_cells§runtime̵published_object_keysdepends_on_skipped_cells§errored$a6937e90-5714-4023-aaf5-02909c53daa7queued¤logsrunning¦outputbody+
mimetext/htmlrootassigneelast_run_timestampAڎípersist_js_state·has_pluto_hook_features§cell_id$a6937e90-5714-4023-aaf5-02909c53daa7depends_on_disabled_cells§runtime%Kpublished_object_keysdepends_on_skipped_cells§errored$b496ac83-b3c7-4758-994e-7534abc56932queued¤logsrunning¦outputbody0.0:0.01:0.0mimetext/plainrootassigneelast_run_timestampAڎhpersist_js_state·has_pluto_hook_features§cell_id$b496ac83-b3c7-4758-994e-7534abc56932depends_on_disabled_cells§runtime>Ypublished_object_keysdepends_on_skipped_cells§errored$df840868-75d4-4687-8556-19eeab1e4115queued¤logsrunning¦outputbodyق

Integration in Pluto (with PlutoUI)

mimetext/htmlrootassigneelast_run_timestampAڎypersist_js_state·has_pluto_hook_features§cell_id$df840868-75d4-4687-8556-19eeab1e4115depends_on_disabled_cells§runtime published_object_keysdepends_on_skipped_cells§errored$d353c065-7802-4f18-8492-008b860b9379queued¤logsrunning¦outputbody6

Makie

mimetext/htmlrootassigneelast_run_timestampAڎxpersist_js_state·has_pluto_hook_features§cell_id$d353c065-7802-4f18-8492-008b860b9379depends_on_disabled_cells§runtimepublished_object_keysdepends_on_skipped_cells§errored$5b5f4616-0f66-455a-8e90-4f4027befc51queued¤logsrunning¦outputbody~

Interactivity and animations via WGLMakie

mimetext/htmlrootassigneelast_run_timestampAڎxYGpersist_js_state·has_pluto_hook_features§cell_id$5b5f4616-0f66-455a-8e90-4f4027befc51depends_on_disabled_cells§runtimeӵpublished_object_keysdepends_on_skipped_cells§errored$13c42895-ad10-4f99-adc2-a3f371987d56queued¤logsrunning¦outputbody

We recommend to put all the commands related to the Makie animation (usually starting with fig = Figure(...) and ending with fig) in a let ... end block. Hence all variables defined in the block are defined locally. In particular they are not reactive and the same variable name (e.g. fig, ax, etc.) can be used in several let ... end blocks.

Warning

Since some interactive components (e.g. Slider) are also exported by other packages (e.g. PlutoUI), you may need to write Makie.Slider to avoid ambiguity.

mimetext/htmlrootassigneelast_run_timestampAڎy{ٰpersist_js_state·has_pluto_hook_features§cell_id$13c42895-ad10-4f99-adc2-a3f371987d56depends_on_disabled_cells§runtime=published_object_keysdepends_on_skipped_cells§errored$6d79f301-b6b4-40be-b48e-e194466b5170queued¤logsrunning¦outputbody

Note

The plot above is internaly updated thanks to the Observable type. It is not replotted each time val is modified. Compare with:

let
	val_non_obs = 0:0.01:val
	x = @. exp(- val_non_obs/8) * cos(val_non_obs)
	y = @. exp(- val_non_obs/8) * sin(val_non_obs)
	lines(x,y, axis=(;limits=(-1,2,-1,1)))
end
mimetext/htmlrootassigneelast_run_timestampAڎzdRpersist_js_state·has_pluto_hook_features§cell_id$6d79f301-b6b4-40be-b48e-e194466b5170depends_on_disabled_cells§runtimeIӵpublished_object_keysdepends_on_skipped_cells§errored$d6c97e29-74b6-4be3-bf2a-0aba966e1eadqueued¤logsrunning¦outputbody

Warning

This notedbook cannot be viewed statically online (as a featured notebook), you need to Run this notebook to see the plots.

mimetext/htmlrootassigneelast_run_timestampAڎx~$persist_js_state·has_pluto_hook_features§cell_id$d6c97e29-74b6-4be3-bf2a-0aba966e1eaddepends_on_disabled_cells§runtimev4published_object_keysdepends_on_skipped_cells§errored$2220f4b9-02bd-4540-a32e-124b90cd3033queued¤logsrunning¦outputbodyٔ

Makie animations can be integrated almost seamlessly into Pluto notebooks via the WGLMakie backend.

mimetext/htmlrootassigneelast_run_timestampAڎyVpersist_js_state·has_pluto_hook_features§cell_id$2220f4b9-02bd-4540-a32e-124b90cd3033depends_on_disabled_cells§runtimepublished_object_keysdepends_on_skipped_cells§errored$96269a69-e678-4a9f-87c2-6215032b42d1queued¤logsrunning¦outputbodyObservable(0.0:0.1:0.0) mimetext/plainrootassigneeval_obslast_run_timestampAڎ{ްpersist_js_state·has_pluto_hook_features§cell_id$96269a69-e678-4a9f-87c2-6215032b42d1depends_on_disabled_cells§runtimeCpublished_object_keysdepends_on_skipped_cells§errored$2ed1866c-1d9a-4992-a98d-4492ebe8ca44queued¤logsrunning¦outputbody:

Here is an example of interactive plot. You can push the Live Update button to get a moving curve. It is taken from Makie documentation on toggles. You may have to manually run the cell below.

mimetext/htmlrootassigneelast_run_timestampAڎxkpersist_js_state·has_pluto_hook_features§cell_id$2ed1866c-1d9a-4992-a98d-4492ebe8ca44depends_on_disabled_cells§runtimeMpublished_object_keysdepends_on_skipped_cells§errored$9d306b48-df32-11f0-b15f-7540889fd2b7queued¤logsrunning¦outputbodymimetext/plainrootassigneelast_run_timestampAڎ3mimetext/htmlrootassigneelast_run_timestampAڎADpersist_js_state·has_pluto_hook_features§cell_id$b8b581e9-5085-4763-8f46-2aa718925635depends_on_disabled_cells§runtime}published_object_keysdepends_on_skipped_cells§errored$9e86e965-7a3e-43bc-930a-5d916273770fqueued¤logsrunning¦outputbody.

There is an intermediate solution that combines Makie's Observable with PlutoUI's interactivity. Here is a simple example with a PlutoUI.Slider where we want to plot some values generated from a range between 0 and val.

mimetext/htmlrootassigneelast_run_timestampAڎypersist_js_state·has_pluto_hook_features§cell_id$9e86e965-7a3e-43bc-930a-5d916273770fdepends_on_disabled_cells§runtime#published_object_keysdepends_on_skipped_cells§errored$91a90dc6-4f33-403d-b7f2-837fed4a0304queued¤logsrunning¦outputbodyٽ

Finally, here is another animation example taken from Makie documentation on buttons.

mimetext/htmlrootassigneelast_run_timestampAڎypersist_js_state·has_pluto_hook_features§cell_id$91a90dc6-4f33-403d-b7f2-837fed4a0304depends_on_disabled_cells§runtimenpublished_object_keysdepends_on_skipped_cells§errored$9cf1da97-dcb0-4691-8597-44bc62dff257queued¤logsrunning¦outputbodyو

Integration in Pluto (without PlutoUI)

mimetext/htmlrootassigneelast_run_timestampAڎy: persist_js_state·has_pluto_hook_features§cell_id$9cf1da97-dcb0-4691-8597-44bc62dff257depends_on_disabled_cells§runtimeSpublished_object_keysdepends_on_skipped_cells§errored$86f8bb60-7e4c-4acd-af9c-ada0c589f7a5queued¤logsrunning¦outputbody

Then, we initialize an Observable. The argument 0.0:0.1:0.0 is only used for initialization. It only has to respect the type that we want, i.e. StepRange here. In case you don't know the type in advance, you could force it to be Any via val_obs = Observable{Any}(0) for instance.

mimetext/htmlrootassigneelast_run_timestampAڎzpersist_js_state·has_pluto_hook_features§cell_id$86f8bb60-7e4c-4acd-af9c-ada0c589f7a5depends_on_disabled_cells§runtime$published_object_keysdepends_on_skipped_cells§errored$4acece79-c67c-420e-a688-679d4c4dbe36queued¤logsrunning¦outputbody

The most natural way to put interactivity within a Pluto notebook is to use the @bind macro from PlutoUI.jl coupled with Pluto reactivity. The PlutoUI notebook gives lots of examples to elaborate on.

The objective of the present notebook is to present an alternative using the Makie ecosystem.

Warning

The Makie package is a powerful plotting package, but it takes a while to install and precompile. Therefore, this notebook will be a bit slow to start the first time you run it.

mimetext/htmlrootassigneelast_run_timestampAڎxlpersist_js_state·has_pluto_hook_features§cell_id$4acece79-c67c-420e-a688-679d4c4dbe36depends_on_disabled_cells§runtimeUpublished_object_keysdepends_on_skipped_cells§errored$78ccde0f-fdca-4db3-9af3-caa3a0963b23queued¤logsrunning¦outputbodymimetext/plainrootassigneelast_run_timestampAڎzpersist_js_state·has_pluto_hook_features§cell_id$78ccde0f-fdca-4db3-9af3-caa3a0963b23depends_on_disabled_cells§runtimeCصpublished_object_keysdepends_on_skipped_cells§errored$6a54d18f-45ec-4917-843e-d6af2660525cqueued¤logsrunning¦outputbody`

There are two main drawbacks when using pure Makie animations:

  1. it relies on the heavy Makie ecosystem (long to precompile and run),

  2. it is harder to get global dependencies in your animations than if you are using PlutoUI and reactivity.

Hence, if you plan to share your notebook you should avoid to use Makie.

However, if you plan to produce slides for a presentation, using Makie is a great option. It gives high quality plots and highly customizable animations that will make your slides shine.

mimetext/htmlrootassigneelast_run_timestampAڎ{،persist_js_state·has_pluto_hook_features§cell_id$6a54d18f-45ec-4917-843e-d6af2660525cdepends_on_disabled_cells§runtime (Apublished_object_keysdepends_on_skipped_cells§errored$917f2df5-f63f-4937-b1e0-b60ed4351d9fqueued¤logsrunning¦outputbody@

Conclusion

mimetext/htmlrootassigneelast_run_timestampAڎzpersist_js_state·has_pluto_hook_features§cell_id$917f2df5-f63f-4937-b1e0-b60ed4351d9fdepends_on_disabled_cells§runtime۵published_object_keysdepends_on_skipped_cells§errored$9d9b338e-c859-4089-aa27-40742dbfd054queued¤logsrunning¦outputbody+
mimetext/htmlrootassigneelast_run_timestampAڎwpersist_js_state·has_pluto_hook_features§cell_id$9d9b338e-c859-4089-aa27-40742dbfd054depends_on_disabled_cells§runtimeD$published_object_keysdepends_on_skipped_cells§errored$106e4592-7ddc-4388-b92d-d41933828032queued¤logsrunning¦outputbody#

If you are not familiar with Makie, here is Makie's basic tutorial dealing with static single plots and Makie's advanced tutorial dealing with layouts of multiple plots.

If you are familiar with Makie for static plots, but not for animations, have a look at Makie's animation tutorial.

mimetext/htmlrootassigneelast_run_timestampAڎypersist_js_state·has_pluto_hook_features§cell_id$106e4592-7ddc-4388-b92d-d41933828032depends_on_disabled_cells§runtime"-published_object_keysdepends_on_skipped_cells§errored±cell_dependencies$048f54ba-45d1-49e2-b19d-7ef634c77cf0precedence_heuristic cell_id$048f54ba-45d1-49e2-b19d-7ef634c77cf0downstream_cells_mapupstream_cells_mapsin:hidexdecorations!Labellift@__dot__GridLayoutlines!-range^on+Toggle*ObservableFigureAxis$b1658a17-b59f-4c35-b7a0-1503e377c731precedence_heuristic cell_id$b1658a17-b59f-4c35-b7a0-1503e377c731downstream_cells_mapupstream_cells_map@md_strgetindex$774f1c41-7a84-401a-950c-466cf05fcd92precedence_heuristic cell_id$774f1c41-7a84-401a-950c-466cf05fcd92downstream_cells_mapupstream_cells_map@md_strgetindex$a6937e90-5714-4023-aaf5-02909c53daa7precedence_heuristic cell_id$a6937e90-5714-4023-aaf5-02909c53daa7downstream_cells_mapxyupstream_cells_mapexpMakie@liftlines@__dot__Makie.lift-val_obs$96269a69-e678-4a9f-87c2-6215032b42d1/*cossin$b496ac83-b3c7-4758-994e-7534abc56932precedence_heuristic cell_id$b496ac83-b3c7-4758-994e-7534abc56932downstream_cells_mapupstream_cells_map:val_obs$96269a69-e678-4a9f-87c2-6215032b42d1val$b8b581e9-5085-4763-8f46-2aa718925635$df840868-75d4-4687-8556-19eeab1e4115precedence_heuristic cell_id$df840868-75d4-4687-8556-19eeab1e4115downstream_cells_mapupstream_cells_map@md_strgetindex$d353c065-7802-4f18-8492-008b860b9379precedence_heuristic cell_id$d353c065-7802-4f18-8492-008b860b9379downstream_cells_mapupstream_cells_map@md_strgetindex$5b5f4616-0f66-455a-8e90-4f4027befc51precedence_heuristic cell_id$5b5f4616-0f66-455a-8e90-4f4027befc51downstream_cells_mapupstream_cells_map@md_strgetindex$13c42895-ad10-4f99-adc2-a3f371987d56precedence_heuristic cell_id$13c42895-ad10-4f99-adc2-a3f371987d56downstream_cells_mapupstream_cells_map@md_strgetindex$6d79f301-b6b4-40be-b48e-e194466b5170precedence_heuristic cell_id$6d79f301-b6b4-40be-b48e-e194466b5170downstream_cells_mapupstream_cells_map@md_strgetindex$d6c97e29-74b6-4be3-bf2a-0aba966e1eadprecedence_heuristic cell_id$d6c97e29-74b6-4be3-bf2a-0aba966e1eaddownstream_cells_mapupstream_cells_map@md_strgetindex$2220f4b9-02bd-4540-a32e-124b90cd3033precedence_heuristic cell_id$2220f4b9-02bd-4540-a32e-124b90cd3033downstream_cells_mapupstream_cells_map@md_strgetindex$96269a69-e678-4a9f-87c2-6215032b42d1precedence_heuristic cell_id$96269a69-e678-4a9f-87c2-6215032b42d1downstream_cells_mapval_obs$b496ac83-b3c7-4758-994e-7534abc56932$a6937e90-5714-4023-aaf5-02909c53daa7upstream_cells_map:Observable$2ed1866c-1d9a-4992-a98d-4492ebe8ca44precedence_heuristic cell_id$2ed1866c-1d9a-4992-a98d-4492ebe8ca44downstream_cells_mapupstream_cells_map@md_strgetindex$9d306b48-df32-11f0-b15f-7540889fd2b7precedence_heuristiccell_id$9d306b48-df32-11f0-b15f-7540889fd2b7downstream_cells_mapWGLMakieupstream_cells_map$b8b581e9-5085-4763-8f46-2aa718925635precedence_heuristic cell_id$b8b581e9-5085-4763-8f46-2aa718925635downstream_cells_mapval$b496ac83-b3c7-4758-994e-7534abc56932upstream_cells_mapCoreBase:PlutoRunner.create_bondPlutoRunnerPlutoUI$78ccde0f-fdca-4db3-9af3-caa3a0963b23Core.applicable@bindBase.getPlutoUI.Slider$9e86e965-7a3e-43bc-930a-5d916273770fprecedence_heuristic cell_id$9e86e965-7a3e-43bc-930a-5d916273770fdownstream_cells_mapupstream_cells_map@md_strgetindex$91a90dc6-4f33-403d-b7f2-837fed4a0304precedence_heuristic cell_id$91a90dc6-4f33-403d-b7f2-837fed4a0304downstream_cells_mapupstream_cells_map@md_strgetindex$9cf1da97-dcb0-4691-8597-44bc62dff257precedence_heuristic cell_id$9cf1da97-dcb0-4691-8597-44bc62dff257downstream_cells_mapupstream_cells_map@md_strgetindex$86f8bb60-7e4c-4acd-af9c-ada0c589f7a5precedence_heuristic cell_id$86f8bb60-7e4c-4acd-af9c-ada0c589f7a5downstream_cells_mapupstream_cells_map@md_strgetindex$4acece79-c67c-420e-a688-679d4c4dbe36precedence_heuristic cell_id$4acece79-c67c-420e-a688-679d4c4dbe36downstream_cells_mapupstream_cells_map@md_strgetindex$78ccde0f-fdca-4db3-9af3-caa3a0963b23precedence_heuristiccell_id$78ccde0f-fdca-4db3-9af3-caa3a0963b23downstream_cells_mapPlutoUI$b8b581e9-5085-4763-8f46-2aa718925635upstream_cells_map$6a54d18f-45ec-4917-843e-d6af2660525cprecedence_heuristic cell_id$6a54d18f-45ec-4917-843e-d6af2660525cdownstream_cells_mapupstream_cells_map@md_strgetindex$917f2df5-f63f-4937-b1e0-b60ed4351d9fprecedence_heuristic cell_id$917f2df5-f63f-4937-b1e0-b60ed4351d9fdownstream_cells_mapupstream_cells_map@md_strgetindex$9d9b338e-c859-4089-aa27-40742dbfd054precedence_heuristic cell_id$9d9b338e-c859-4089-aa27-40742dbfd054downstream_cells_mapupstream_cells_map:MakieliftLinRangeGridLayoutcgradbarplot!ylims!on+notifyMakie.ButtonObservableFigureAxis$106e4592-7ddc-4388-b92d-d41933828032precedence_heuristic cell_id$106e4592-7ddc-4388-b92d-d41933828032downstream_cells_mapupstream_cells_map@md_strgetindexcell_execution_order$9d306b48-df32-11f0-b15f-7540889fd2b7$78ccde0f-fdca-4db3-9af3-caa3a0963b23$5b5f4616-0f66-455a-8e90-4f4027befc51$d6c97e29-74b6-4be3-bf2a-0aba966e1ead$4acece79-c67c-420e-a688-679d4c4dbe36$2ed1866c-1d9a-4992-a98d-4492ebe8ca44$048f54ba-45d1-49e2-b19d-7ef634c77cf0$d353c065-7802-4f18-8492-008b860b9379$106e4592-7ddc-4388-b92d-d41933828032$9cf1da97-dcb0-4691-8597-44bc62dff257$2220f4b9-02bd-4540-a32e-124b90cd3033$13c42895-ad10-4f99-adc2-a3f371987d56$91a90dc6-4f33-403d-b7f2-837fed4a0304$9d9b338e-c859-4089-aa27-40742dbfd054$df840868-75d4-4687-8556-19eeab1e4115$9e86e965-7a3e-43bc-930a-5d916273770f$b8b581e9-5085-4763-8f46-2aa718925635$86f8bb60-7e4c-4acd-af9c-ada0c589f7a5$96269a69-e678-4a9f-87c2-6215032b42d1$b1658a17-b59f-4c35-b7a0-1503e377c731$b496ac83-b3c7-4758-994e-7534abc56932$a6937e90-5714-4023-aaf5-02909c53daa7$774f1c41-7a84-401a-950c-466cf05fcd92$6d79f301-b6b4-40be-b48e-e194466b5170$917f2df5-f63f-4937-b1e0-b60ed4351d9f$6a54d18f-45ec-4917-843e-d6af2660525clast_hot_reload_timeshortpathWGLMakie.jlprocess_statusreadypathC/home/fons/featured-slider-server/featured_fix/src/plot/WGLMakie.jlpluto_versionv1.0.0last_save_timeAڎucell_order$5b5f4616-0f66-455a-8e90-4f4027befc51$d6c97e29-74b6-4be3-bf2a-0aba966e1ead$4acece79-c67c-420e-a688-679d4c4dbe36$2ed1866c-1d9a-4992-a98d-4492ebe8ca44$048f54ba-45d1-49e2-b19d-7ef634c77cf0$d353c065-7802-4f18-8492-008b860b9379$106e4592-7ddc-4388-b92d-d41933828032$9cf1da97-dcb0-4691-8597-44bc62dff257$2220f4b9-02bd-4540-a32e-124b90cd3033$9d306b48-df32-11f0-b15f-7540889fd2b7$13c42895-ad10-4f99-adc2-a3f371987d56$91a90dc6-4f33-403d-b7f2-837fed4a0304$9d9b338e-c859-4089-aa27-40742dbfd054$df840868-75d4-4687-8556-19eeab1e4115$78ccde0f-fdca-4db3-9af3-caa3a0963b23$9e86e965-7a3e-43bc-930a-5d916273770f$b8b581e9-5085-4763-8f46-2aa718925635$86f8bb60-7e4c-4acd-af9c-ada0c589f7a5$96269a69-e678-4a9f-87c2-6215032b42d1$b1658a17-b59f-4c35-b7a0-1503e377c731$b496ac83-b3c7-4758-994e-7534abc56932$a6937e90-5714-4023-aaf5-02909c53daa7$774f1c41-7a84-401a-950c-466cf05fcd92$6d79f301-b6b4-40be-b48e-e194466b5170$917f2df5-f63f-4937-b1e0-b60ed4351d9f$6a54d18f-45ec-4917-843e-d6af2660525cjulia_versionv1.12.4published_objectsnbpkginstall_time_nsvwEinstantiatedòinstalled_versionsWGLMakie0.13.10PlutoUI0.7.81!__internal_julia_manifest_version1.12.4__internal_julia_version1.12.4terminal_outputsWGLMakie& Waiting for other notebooks to finish Pkg operations... === Resolving... ===  Project No packages added to or removed from `~/.julia/scratchspaces/c3e4b0f8-55cb-11ea-2926-15256bba5781/pkg_envs/env_ugmdgrhwvr/Project.toml`  Manifest No packages added to or removed from `~/.julia/scratchspaces/c3e4b0f8-55cb-11ea-2926-15256bba5781/pkg_envs/env_ugmdgrhwvr/Manifest.toml` Instantiating... === Precompiling... ===nbpkg_sync& Waiting for other notebooks to finish Pkg operations... === Resolving... ===  Project No packages added to or removed from `~/.julia/scratchspaces/c3e4b0f8-55cb-11ea-2926-15256bba5781/pkg_envs/env_ugmdgrhwvr/Project.toml`  Manifest No packages added to or removed from `~/.julia/scratchspaces/c3e4b0f8-55cb-11ea-2926-15256bba5781/pkg_envs/env_ugmdgrhwvr/Manifest.toml` Instantiating... === Precompiling... ===PlutoUI& Waiting for other notebooks to finish Pkg operations... === Resolving... ===  Project No packages added to or removed from `~/.julia/scratchspaces/c3e4b0f8-55cb-11ea-2926-15256bba5781/pkg_envs/env_ugmdgrhwvr/Project.toml`  Manifest No packages added to or removed from `~/.julia/scratchspaces/c3e4b0f8-55cb-11ea-2926-15256bba5781/pkg_envs/env_ugmdgrhwvr/Manifest.toml` Instantiating... === Precompiling... ===enabled÷restart_recommended_msgrestart_required_msgbusy_packageswaiting_for_permission,waiting_for_permission_but_probably_disabled«cell_inputs$048f54ba-45d1-49e2-b19d-7ef634c77cf0cell_id$048f54ba-45d1-49e2-b19d-7ef634c77cf0codeUlet figurewidth = 600 fig = Figure(size=(figurewidth,300)) ax = Axis(fig[1, 1], limits = (0, 600, -2, 2)) hidexdecorations!(ax) t = Observable(0.0) points = lift(t) do t x = range(t-1, t+1, length = 500) @. sin(x) * sin(2x) * sin(4x) * sin(23x) end lines!(ax, points, color = (1:500) .^ 2, linewidth = 2, colormap = [(:blue, 0.0), :blue]) gl = GridLayout(fig[2, 1], tellwidth = false) Label(gl[1, 1], "Live Update") toggle = Toggle(gl[1, 2], active = false) on(fig.scene.events.tick) do tick toggle.active[] || return t[] += tick.delta_time end fig endmetadatashow_logsèdisabled®skip_as_script«code_folded$b1658a17-b59f-4c35-b7a0-1503e377c731cell_id$b1658a17-b59f-4c35-b7a0-1503e377c731codeٖmd"The following cell automatically updates the content of the observable `val_obs` each time we move the slider. In turn, it updates the plot below."metadatashow_logsèdisabled®skip_as_script«code_folded$774f1c41-7a84-401a-950c-466cf05fcd92cell_id$774f1c41-7a84-401a-950c-466cf05fcd92codemd""" !!! warning The code must be separated into four cells as above (slider, definition of the observable, update of the observable, plot). *In fact, the definition of the observable could be included in the "plot cell".* """metadatashow_logsèdisabled®skip_as_script«code_folded$a6937e90-5714-4023-aaf5-02909c53daa7cell_id$a6937e90-5714-4023-aaf5-02909c53daa7codeٍbegin x = @lift(@. exp(-$val_obs/8)*cos($val_obs)) y = @lift(@. exp(-$val_obs/8)*sin($val_obs)) lines(x,y, axis=(;limits=(-1,2,-1,1))) endmetadatashow_logsèdisabled®skip_as_script«code_folded$b496ac83-b3c7-4758-994e-7534abc56932cell_id$b496ac83-b3c7-4758-994e-7534abc56932codeval_obs[] = 0:0.01:valmetadatashow_logsèdisabled®skip_as_script«code_folded$df840868-75d4-4687-8556-19eeab1e4115cell_id$df840868-75d4-4687-8556-19eeab1e4115code*md"## Integration in Pluto (with PlutoUI)"metadatashow_logsèdisabled®skip_as_script«code_folded$d353c065-7802-4f18-8492-008b860b9379cell_id$d353c065-7802-4f18-8492-008b860b9379codemd"## Makie"metadatashow_logsèdisabled®skip_as_script«code_folded$5b5f4616-0f66-455a-8e90-4f4027befc51cell_id$5b5f4616-0f66-455a-8e90-4f4027befc51code/md"# Interactivity and animations via WGLMakie"metadatashow_logsèdisabled®skip_as_script«code_folded$13c42895-ad10-4f99-adc2-a3f371987d56cell_id$13c42895-ad10-4f99-adc2-a3f371987d56codemd"We recommend to put all the commands related to the Makie animation (usually starting with `fig = Figure(...)` and ending with `fig`) in a `let ... end` block. Hence all variables defined in the block are defined locally. In particular they are not reactive and the same variable name (e.g. `fig`, `ax`, etc.) can be used in several `let ... end` blocks. !!! warning Since some interactive components (e.g. `Slider`) are also exported by other packages (e.g. PlutoUI), you may need to write `Makie.Slider` to avoid ambiguity. "metadatashow_logsèdisabled®skip_as_script«code_folded$6d79f301-b6b4-40be-b48e-e194466b5170cell_id$6d79f301-b6b4-40be-b48e-e194466b5170codeNmd" !!! note The plot above is internaly updated thanks to the `Observable` type. It is not replotted each time `val` is modified. Compare with: ``` let val_non_obs = 0:0.01:val x = @. exp(- val_non_obs/8) * cos(val_non_obs) y = @. exp(- val_non_obs/8) * sin(val_non_obs) lines(x,y, axis=(;limits=(-1,2,-1,1))) end ``` "metadatashow_logsèdisabled®skip_as_script«code_folded$d6c97e29-74b6-4be3-bf2a-0aba966e1eadcell_id$d6c97e29-74b6-4be3-bf2a-0aba966e1eadcodeٖmd""" !!! warning This notedbook cannot be viewed statically online (as a featured notebook), you need to **Run this notebook** to see the plots. """metadatashow_logsèdisabled®skip_as_script«code_folded$2220f4b9-02bd-4540-a32e-124b90cd3033cell_id$2220f4b9-02bd-4540-a32e-124b90cd3033codeimd"Makie animations can be integrated almost seamlessly into Pluto notebooks via the `WGLMakie` backend."metadatashow_logsèdisabled®skip_as_script«code_folded$96269a69-e678-4a9f-87c2-6215032b42d1cell_id$96269a69-e678-4a9f-87c2-6215032b42d1code!val_obs = Observable(0.0:0.1:0.0)metadatashow_logsèdisabled®skip_as_script«code_folded$2ed1866c-1d9a-4992-a98d-4492ebe8ca44cell_id$2ed1866c-1d9a-4992-a98d-4492ebe8ca44codemd"Here is an example of interactive plot. You can push the *Live Update* button to get a moving curve. It is taken from [Makie documentation on toggles](https://docs.makie.org/stable/reference/blocks/toggle). *You may have to manually run the cell below.*"metadatashow_logsèdisabled®skip_as_script«code_folded$9d306b48-df32-11f0-b15f-7540889fd2b7cell_id$9d306b48-df32-11f0-b15f-7540889fd2b7codeusing WGLMakiemetadatashow_logsèdisabled®skip_as_script«code_folded$b8b581e9-5085-4763-8f46-2aa718925635cell_id$b8b581e9-5085-4763-8f46-2aa718925635code'@bind val PlutoUI.Slider(0.0:0.01:40.0)metadatashow_logsèdisabled®skip_as_script«code_folded$9e86e965-7a3e-43bc-930a-5d916273770fcell_id$9e86e965-7a3e-43bc-930a-5d916273770fcodemd"There is an intermediate solution that combines Makie's `Observable` with PlutoUI's interactivity. Here is a simple example with a `PlutoUI.Slider` where we want to plot some values generated from a range between 0 and `val`."metadatashow_logsèdisabled®skip_as_script«code_folded$91a90dc6-4f33-403d-b7f2-837fed4a0304cell_id$91a90dc6-4f33-403d-b7f2-837fed4a0304codeْmd"Finally, here is another animation example taken from [Makie documentation on buttons](https://docs.makie.org/stable/reference/blocks/button)."metadatashow_logsèdisabled®skip_as_script«code_folded$9cf1da97-dcb0-4691-8597-44bc62dff257cell_id$9cf1da97-dcb0-4691-8597-44bc62dff257code-md"## Integration in Pluto (without PlutoUI)"metadatashow_logsèdisabled®skip_as_script«code_folded$86f8bb60-7e4c-4acd-af9c-ada0c589f7a5cell_id$86f8bb60-7e4c-4acd-af9c-ada0c589f7a5code'md"Then, we initialize an `Observable`. The argument `0.0:0.1:0.0` is only used for initialization. It only has to respect the type that we want, i.e. `StepRange` here. *In case you don't know the type in advance, you could force it to be `Any` via `val_obs = Observable{Any}(0)` for instance.*"metadatashow_logsèdisabled®skip_as_script«code_folded$4acece79-c67c-420e-a688-679d4c4dbe36cell_id$4acece79-c67c-420e-a688-679d4c4dbe36codeLmd"""The most natural way to put interactivity within a **Pluto notebook** is to use the `@bind` macro from `PlutoUI.jl` coupled with Pluto reactivity. The [PlutoUI notebook](https://featured.plutojl.org/basic/plutoui.jl) gives lots of examples to elaborate on. The objective of the present notebook is to present an alternative using the [Makie](https://docs.makie.org/stable/) ecosystem. !!! warning The `Makie` package is a powerful plotting package, but it takes a while to install and precompile. Therefore, this notebook will be a bit slow to start the first time you run it. """metadatashow_logsèdisabled®skip_as_script«code_folded$78ccde0f-fdca-4db3-9af3-caa3a0963b23cell_id$78ccde0f-fdca-4db3-9af3-caa3a0963b23codeusing PlutoUImetadatashow_logsèdisabled®skip_as_script«code_folded$6a54d18f-45ec-4917-843e-d6af2660525ccell_id$6a54d18f-45ec-4917-843e-d6af2660525ccodemd"There are two main drawbacks when using *pure* Makie animations: 1. it relies on the heavy Makie ecosystem (long to precompile and run), 2. it is harder to get global dependencies in your animations than if you are using PlutoUI and reactivity. Hence, if you plan to share your notebook you should avoid to use Makie. However, if you plan to produce slides for a presentation, using Makie is a great option. It gives high quality plots and highly customizable animations that will make your slides shine. "metadatashow_logsèdisabled®skip_as_script«code_folded$917f2df5-f63f-4937-b1e0-b60ed4351d9fcell_id$917f2df5-f63f-4937-b1e0-b60ed4351d9fcodemd"## Conclusion"metadatashow_logsèdisabled®skip_as_script«code_folded$9d9b338e-c859-4089-aa27-40742dbfd054cell_id$9d9b338e-c859-4089-aa27-40742dbfd054codelet fig = Figure() ax = Axis(fig[1, 1]) fig[2, 1] = buttongrid = GridLayout(tellwidth = false) counts = Observable([1, 4, 3, 7, 2]) buttonlabels = [lift(x -> "Count: $(x[i])", counts) for i in 1:5] buttons = buttongrid[1, 1:5] = [Makie.Button(fig, label = l) for l in buttonlabels] for i in 1:5 on(buttons[i].clicks) do n counts[][i] += 1 notify(counts) end end barplot!(counts, color = cgrad(:Spectral)[LinRange(0, 1, 5)]) ylims!(ax, 0, 20) fig endmetadatashow_logsèdisabled®skip_as_script«code_folded$106e4592-7ddc-4388-b92d-d41933828032cell_id$106e4592-7ddc-4388-b92d-d41933828032codemd"If you are not familiar with Makie, here is Makie's [basic tutorial](https://docs.makie.org/stable/tutorials/getting-started) dealing with static single plots and Makie's [advanced tutorial](https://docs.makie.org/stable/tutorials/layout-tutorial) dealing with layouts of multiple plots. If you are familiar with Makie for static plots, but not for animations, have a look at Makie's [animation tutorial](https://docs.makie.org/stable/explanations/animation)."metadatashow_logsèdisabled®skip_as_script«code_foldedënotebook_id$783700a4-6f92-11f1-a5f9-45247ec05a3din_temp_dir¨metadatafrontmatterauthornameJulien Chevallierurlhttps://github.com/juchevalimage\https://image2url.com/r2/default/gifs/1772474106000-b9bdee0b-91fe-4d82-af83-2bc1fec8c734.giftitleAnimations with WGLMakietagsvisualisationanimationplottingdescriptionCAn introduction to animations with or without the use of PlutoUI.jl