# using GLMakie using CairoMakie # Use a custom theme for fun include("cyberpunk_theme.jl") set_theme!(cyberpunk_theme) time = Observable(0.0) time[] = 10 time x = @lift(1 + $time) y = @lift(5 + 0.5*($time)) # look at time time # 0. Create `Observable` and listeners `x` and `y`: time = Observable(0.0) time[] = 10 # initial value x = @lift(1 + $time) y = @lift(5 + 0.5*($time)) # 1. Create a figure fig = scatter(x, y, color = :red, markersize = 20, axis = (title = @lift("t = $(round($time, digits =1))"),)) # 2. Next, pass a function that modifies this figure frame by frame to record. """ Update the value of observable `time` to be equal to t, where t is from the timestamps iterator (i.e. a value between 0 and 5) """ function move_dot(t) time[] = t end # 3. pass an iterable that has the same number of elements as frames in the animation framerate = 30 timestamps = range(0, 5, step=1/framerate) # 4. Create an animation from the function record(move_dot, fig, "moving_dot.gif", timestamps; framerate = framerate) # # Alternate with `do` notation to make an anonymous function: # record(fig, "moving_dot.gif", timestamps; # framerate = framerate) do t # time[] = t # end # 0. Create a 2-d `Observable`/listener combo location = Observable(Point2f(0,0)) # 1. Create a figure fig, ax, scatterplot = scatter(location, color = :red, markersize = 20, axis = (title = @lift("t = $($location)"),)) # Pro tip: The scale of the axis doesn't update automatically as the dot moves, # so manually set your limits! limits!(ax, 0, 30, 0, 30) # 2. Next, pass a function that modifies this figure frame by frame to record. """Update the point location at each frame""" function move_dot2(i) location[] = location[] + [0.5, 0.75] end # 3. Pass an iterable that has the same number of elements as frames in the animation framerate = 30 frames = 1:framerate # 4. Create an animation with `record` record(move_dot2, fig, "moving_dot2.gif", frames; framerate = framerate) # 0. Create a 2-d `Observable`/listener combo location = Observable(Point2f(0,0)) # 1. Create a figure fig, ax, scatterplot = scatter(location, color = :red, markersize = 20, axis = (title = @lift("location = $($location))"),)) # Pro tip: The scale of the axis doesn't update automatically as the dot moves, # so manually set your limits! limits!(ax, -10, 10, -10, 10) # 2. Next, pass a function that modifies this figure frame by frame to record. """Take a random step in the x or y direction""" function random_walk(i) xStep = (rand() * 2)-1 yStep = (rand() * 2)-1 # Update the location with a step between -1 and 1 in x and y directions location[] = location[] + [xStep, yStep] end # 3. Pass an iterable that has the same number of elements as frames in the animation framerate = 10 frames = 1:30 # 4. Create an animation with `record` record(random_walk, fig, "random_walk.gif", frames; framerate = framerate) using Random Random.seed!(42) y = rand(50) x = range(1,50) fig = lines(x,y) points = Observable(Point2f[(0, 0)]) fig, ax, lineplot = lines(points) limits!(ax, 0, 50, 0, 1) function update_lines(i) new_point = Point2f(x[i], y[i]) # Observables are arrays, so you can add to them points[] = push!(points[], new_point) end record(update_lines, fig, "moving_lines.gif", 1:50; framerate=12) fig, ax, lineplot = lines(x, y) limits!(ax, 0, 70, 0, 1) new_x = 51:70 # Imagine this is a matrix where each row is a separate forecast for 20 # periods into the future forecast_matrix = rand(Float64, (30,20)) # new_y = Observable(forecast_matrix[1,:]) new_y = Observable(forecast_matrix[1,:]) function step_through_forecasts(i) new_y[] = forecast_matrix[i,:] end lines!(new_x, new_y) record(step_through_forecasts, fig, "forecast_uncertainty.gif", 1:20; framerate=2)