{ "cells": [ { "attachments": {}, "cell_type": "markdown", "id": "2dc760a9", "metadata": {}, "source": [ "# Animations in Makie\n", "\n", "Experimenting with `Makie` [animations](https://docs.makie.org/v0.18.0/documentation/animation/index.html) to see if it's viable.\n", "\n", "So far, I haven't found a viable use case for this yet since the base `Plots` library in Julia is so good and the syntax there is more intuitive." ] }, { "cell_type": "code", "execution_count": 1, "id": "22e32393", "metadata": {}, "outputs": [], "source": [ "# using GLMakie\n", "using CairoMakie\n", "# Use a custom theme for fun\n", "include(\"cyberpunk_theme.jl\")\n", "set_theme!(cyberpunk_theme)" ] }, { "cell_type": "markdown", "id": "63924e10", "metadata": {}, "source": [ "From the docs:\n", "\n", "> To create an animation you need to use the `record` function.\n", "\n", "> * First you create a `Figure`\n", "> * Next, you pass a function that modifies this figure frame-by-frame to record. Any changes you make to the figure or its plots will appear in the final animation. \n", "> * You also need to pass an iterable which has as many elements as you want frames in your animation. The function that you pass as the first argument is called with each element from this iterator over the course of the animation." ] }, { "attachments": {}, "cell_type": "markdown", "id": "b103b4e3", "metadata": {}, "source": [ "## A simple goal: Create a dot that moves up and to the right\n", "\n", "Let's try to keep this example really, really simple: animate a dot that's moving up and to the right as time passes by. \n", "\n", "To do that, I think we have to understand two key concepts: `Observable`s and *listeners*.\n", "\n", "* `Observable`: A variable that changes with each frame in your animation\n", "* *listeners*: Functions of the `Observable`" ] }, { "cell_type": "markdown", "id": "80cf7dad", "metadata": {}, "source": [ "### Observables\n", "\n", "An `Observable` is something that `Makie` is designed to 'listen' to and react to changes. We declare an `Observable` like below:" ] }, { "cell_type": "code", "execution_count": 2, "id": "5eb53454", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "Observable(0.0)\n" ] }, "execution_count": 2, "metadata": {}, "output_type": "execute_result" } ], "source": [ "time = Observable(0.0)" ] }, { "cell_type": "markdown", "id": "efe7266f", "metadata": {}, "source": [ "The above code created an `Observable` called `time` that currently has the value of 0.0. We can update the current value of `time` by simply using this *empty* bracket notation:" ] }, { "cell_type": "code", "execution_count": 3, "id": "429ce338", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "Observable(10.0)\n" ] }, "execution_count": 3, "metadata": {}, "output_type": "execute_result" } ], "source": [ "time[] = 10\n", "time" ] }, { "cell_type": "markdown", "id": "a60a4f81", "metadata": {}, "source": [ "### Create listeners:\n", "\n", "Use the `@lift` macro to define a relationship with an `Observable`. \n", "\n", "In this example, both the `x` and `y` coordinates will depend only on `time`:" ] }, { "cell_type": "code", "execution_count": 4, "id": "f94421d6", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "Observable(10.0)\n", " 0 => map((::var\"#1#2\")(arg1) in Main)\n", " 0 => map((::var\"#3#4\")(arg1) in Main)\n" ] }, "execution_count": 4, "metadata": {}, "output_type": "execute_result" } ], "source": [ "x = @lift(1 + $time)\n", "y = @lift(5 + 0.5*($time))\n", "# look at time\n", "time" ] }, { "cell_type": "markdown", "id": "0c654606", "metadata": {}, "source": [ "If we look at `time` again, we should see that it has 2 listeners now." ] }, { "attachments": {}, "cell_type": "markdown", "id": "4816d022", "metadata": {}, "source": [ "After we've created our `Observable` and *listeners* `x` and `y`, we need to follow 3 steps to create our animation:\n", "\n", "1. Create a figure: `fig`\n", "2. Create an iterator that has the same number of elements as frames in the animation: `timestamps`\n", "3. Create a function that changes the `Observable`: `move_dot`\n", " * Changes the value of `time`, which in turn, changes `x` and `y`" ] }, { "cell_type": "code", "execution_count": 5, "id": "507c10d3", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "\"moving_dot.gif\"" ] }, "execution_count": 5, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# 0. Create `Observable` and listeners `x` and `y`:\n", "time = Observable(0.0)\n", "time[] = 10 # initial value\n", "x = @lift(1 + $time) \n", "y = @lift(5 + 0.5*($time))\n", "\n", "# 1. Create a figure\n", "fig = scatter(x, y, color = :red, markersize = 20,\n", " axis = (title = @lift(\"t = $(round($time, digits =1))\"),))\n", "\n", "# 2. Next, pass a function that modifies this figure frame by frame to record.\n", "\"\"\"\n", "Update the value of observable `time` to be equal to t, \n", "where t is from the timestamps iterator (i.e. a value between 0 and 5)\n", "\"\"\"\n", "function move_dot(t)\n", " time[] = t\n", "end\n", "\n", "# 3. pass an iterable that has the same number of elements as frames in the animation\n", "framerate = 30\n", "timestamps = range(0, 5, step=1/framerate)\n", "\n", "# 4. Create an animation from the function\n", "record(move_dot, fig, \"moving_dot.gif\", timestamps;\n", " framerate = framerate) \n", "\n", "# # Alternate with `do` notation to make an anonymous function:\n", "# record(fig, \"moving_dot.gif\", timestamps;\n", "# framerate = framerate) do t\n", "# time[] = t\n", "# end" ] }, { "attachments": {}, "cell_type": "markdown", "id": "88e62728", "metadata": {}, "source": [ "What this code does:\n", "* for every `t` in the iterator `timestamps` (which is a `range` between 0 and 5)\n", "* call the `move_dot` function with a single `t` as input\n", "* each frame of animation will be based on each visualization after `move_dot` changes the `x` and `y` values" ] }, { "cell_type": "markdown", "id": "a94dcc7b", "metadata": {}, "source": [ "![img](moving_dot.gif)" ] }, { "attachments": {}, "cell_type": "markdown", "id": "b202c38f", "metadata": {}, "source": [ "What about using a `Point2f` type as the `Observable`? Instead of setting `x` and `y` as listeners that depend on `time`, we could instead change the type of `Observable` so that it's a 2d point." ] }, { "cell_type": "code", "execution_count": 6, "id": "3d115afc", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "\"moving_dot2.gif\"" ] }, "execution_count": 6, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# 0. Create a 2-d `Observable`/listener combo\n", "location = Observable(Point2f(0,0))\n", "\n", "# 1. Create a figure\n", "fig, ax, scatterplot = scatter(location, color = :red, markersize = 20,\n", " axis = (title = @lift(\"t = $($location)\"),))\n", "\n", "# Pro tip: The scale of the axis doesn't update automatically as the dot moves,\n", "# so manually set your limits!\n", "limits!(ax, 0, 30, 0, 30)\n", "\n", "# 2. Next, pass a function that modifies this figure frame by frame to record.\n", "\"\"\"Update the point location at each frame\"\"\"\n", "function move_dot2(i)\n", " location[] = location[] + [0.5, 0.75]\n", "end\n", "\n", "# 3. Pass an iterable that has the same number of elements as frames in the animation\n", "framerate = 30\n", "frames = 1:framerate\n", "\n", "# 4. Create an animation with `record`\n", "record(move_dot2, fig, \"moving_dot2.gif\", frames;\n", " framerate = framerate) " ] }, { "cell_type": "markdown", "id": "4cfdf17c", "metadata": {}, "source": [ "![img](moving_dot2.gif)" ] }, { "attachments": {}, "cell_type": "markdown", "id": "01fef5ca", "metadata": {}, "source": [ "### A randomly moving dot\n", "\n", "Now, let's step it up a little and have this dot move a little more randomly. I want this dot to do a random walk." ] }, { "cell_type": "code", "execution_count": 7, "id": "af85969b", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "\"random_walk.gif\"" ] }, "execution_count": 7, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# 0. Create a 2-d `Observable`/listener combo\n", "location = Observable(Point2f(0,0))\n", "\n", "# 1. Create a figure\n", "fig, ax, scatterplot = scatter(location, color = :red, markersize = 20,\n", " axis = (title = @lift(\"location = $($location))\"),))\n", "\n", "# Pro tip: The scale of the axis doesn't update automatically as the dot moves,\n", "# so manually set your limits!\n", "limits!(ax, -10, 10, -10, 10)\n", "\n", "# 2. Next, pass a function that modifies this figure frame by frame to record.\n", "\"\"\"Take a random step in the x or y direction\"\"\"\n", "function random_walk(i)\n", " xStep = (rand() * 2)-1\n", " yStep = (rand() * 2)-1\n", " # Update the location with a step between -1 and 1 in x and y directions\n", " location[] = location[] + [xStep, yStep]\n", "end\n", "\n", "# 3. Pass an iterable that has the same number of elements as frames in the animation\n", "framerate = 10\n", "frames = 1:30\n", "\n", "# 4. Create an animation with `record`\n", "record(random_walk, fig, \"random_walk.gif\", frames;\n", " framerate = framerate) " ] }, { "cell_type": "markdown", "id": "2f102066", "metadata": {}, "source": [ "![img](random_walk.gif)" ] }, { "attachments": {}, "cell_type": "markdown", "id": "e938073a", "metadata": {}, "source": [ "## Line Plot Example\n", "\n", "Next, we'll compare the output from base `Plots` to animate a line plot. Here's an example of the syntax for animating a line plot with `Plots`:\n", "\n", "```julia\n", "using Plots\n", "# Simple dataset of 50 random numbers\n", "y = rand(50)\n", "\n", "# Use the @animate macro in front of a loop to create each frame of your animation\n", "anim = @animate for i in 1:50\n", " # At each iteration we will plot a new subset of the data\n", " # I set the xlimits and ylimits so the x/y axes don't autofit as the data grows\n", " plot(y[1:i], \n", " xlims=(1,50),\n", " ylims=(0,1))\n", "end\n", "\n", "# Save the animation as a gif and display it\n", "gif(anim)\n", "```" ] }, { "attachments": {}, "cell_type": "markdown", "id": "27ef60f6", "metadata": {}, "source": [ "The above code should create a line plot where the lines grow from left to right." ] }, { "attachments": {}, "cell_type": "markdown", "id": "d86f54a0", "metadata": {}, "source": [ "Let's see how `Makie` compares:" ] }, { "cell_type": "code", "execution_count": 8, "id": "fd6483bb", "metadata": {}, "outputs": [ { "data": { "image/png": "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" }, "execution_count": 8, "metadata": {}, "output_type": "execute_result" } ], "source": [ "using Random\n", "Random.seed!(42)\n", "\n", "y = rand(50)\n", "x = range(1,50)\n", "fig = lines(x,y)" ] }, { "attachments": {}, "cell_type": "markdown", "id": "62924783", "metadata": {}, "source": [ "Next let's animate it using the `Point2f` syntax to hold our points. An `Observable` is an array so the value will start at (0,0) but we'll append new points to the array for each frame in the animation." ] }, { "cell_type": "code", "execution_count": 9, "id": "cb4c549e", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "\"moving_lines.gif\"" ] }, "execution_count": 9, "metadata": {}, "output_type": "execute_result" } ], "source": [ "points = Observable(Point2f[(0, 0)])\n", "\n", "fig, ax, lineplot = lines(points)\n", "limits!(ax, 0, 50, 0, 1)\n", "\n", "function update_lines(i)\n", " new_point = Point2f(x[i], y[i])\n", " # Observables are arrays, so you can add to them\n", " points[] = push!(points[], new_point)\n", "end\n", "\n", "record(update_lines, fig, \"moving_lines.gif\", 1:50; framerate=12)" ] }, { "attachments": {}, "cell_type": "markdown", "id": "22059a97", "metadata": {}, "source": [ "![img](moving_lines.gif)" ] }, { "attachments": {}, "cell_type": "markdown", "id": "99c2b52d", "metadata": {}, "source": [ "## Applied example: Show Forecast Uncertainty\n", "\n", "Here's how I'd use animations - Imagine we had a time series of historical datapoints and we want to visualize the uncertainty behind our forecast. Typically, you'd show the prediction interval as two horizontal lines that would indicate the high/low boundaries of the prediction interval. But another way to think about that interval is that there are some infinite number of point forecasts that we could generate, each one a possible version of the future. Then, the prediction interval should include some large percentage (say, 95%) of these possible futures. \n", "\n", "We could show that as an animation, and use a mutating function like `lines!` here to show how different forecasts might look:" ] }, { "cell_type": "code", "execution_count": 10, "id": "4f0265f9", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "\"forecast_uncertainty.gif\"" ] }, "execution_count": 10, "metadata": {}, "output_type": "execute_result" } ], "source": [ "\n", "fig, ax, lineplot = lines(x, y)\n", "limits!(ax, 0, 70, 0, 1)\n", "new_x = 51:70\n", "# Imagine this is a matrix where each row is a separate forecast for 20\n", "# periods into the future\n", "forecast_matrix = rand(Float64, (30,20))\n", "\n", "# new_y = Observable(forecast_matrix[1,:])\n", "new_y = Observable(forecast_matrix[1,:])\n", "\n", "function step_through_forecasts(i)\n", " new_y[] = forecast_matrix[i,:]\n", "end\n", "\n", "lines!(new_x, new_y)\n", "\n", "record(step_through_forecasts, fig, \"forecast_uncertainty.gif\", 1:20; framerate=2)" ] }, { "attachments": {}, "cell_type": "markdown", "id": "3e8dbfa0", "metadata": {}, "source": [ "![img](forecast_uncertainty.gif)" ] }, { "attachments": {}, "cell_type": "markdown", "id": "6c7a02fe", "metadata": {}, "source": [] } ], "metadata": { "hide_input": false, "kernelspec": { "display_name": "Julia 1.8.3", "language": "julia", "name": "julia-1.8" }, "language_info": { "file_extension": ".jl", "mimetype": "application/julia", "name": "julia", "version": "1.8.3" }, "toc": { "base_numbering": 1, "nav_menu": {}, "number_sections": true, "sideBar": true, "skip_h1_title": false, "title_cell": "Table of Contents", "title_sidebar": "Contents", "toc_cell": false, "toc_position": {}, "toc_section_display": true, "toc_window_display": false }, "varInspector": { "cols": { "lenName": 16, "lenType": 16, "lenVar": 40 }, "kernels_config": { "python": { "delete_cmd_postfix": "", "delete_cmd_prefix": "del ", "library": "var_list.py", "varRefreshCmd": "print(var_dic_list())" }, "r": { "delete_cmd_postfix": ") ", "delete_cmd_prefix": "rm(", "library": "var_list.r", "varRefreshCmd": "cat(var_dic_list()) " } }, "types_to_exclude": [ "module", "function", "builtin_function_or_method", "instance", "_Feature" ], "window_display": false } }, "nbformat": 4, "nbformat_minor": 5 }