Skip to content

Instantly share code, notes, and snippets.

@SimonDanisch
Last active July 18, 2018 15:03
Show Gist options
  • Select an option

  • Save SimonDanisch/8c59e79e6eaf8267796334bc2e6daa25 to your computer and use it in GitHub Desktop.

Select an option

Save SimonDanisch/8c59e79e6eaf8267796334bc2e6daa25 to your computer and use it in GitHub Desktop.
using Makie
import DiffEqPhysics: SimulationResult
import AbstractPlotting: Plot, default_theme, plot!, to_value
# Probably worth having a macro for this!
function default_theme(scene::SceneLike, ::Type{<: Plot(SimulationResult)})
Theme(
simulation_index = 1
# could also have atom radius etc here
)
end
# The recipe! - will get called for plot(!)(x::SimulationResult)
function AbstractPlotting.plot!(p::Plot(SimulationResult))
result = to_value(p[1]) # first argument is the SimulationResult
# when simulation_index changes, get new positions from the simulation
mpos = lift(p[:simulation_index]) do i
coordinates = get_position(result, result.solution.t[i])
map!(x-> x -= pbc.L * floor(x / pbc.L), coordinates, coordinates)
end
# size shouldn't change, so we might as well get the value instead of signal
pos = to_value(mpos)
N = size(pos, 2)
sizes = repeat([0.02, 0.01, 0.01] .* 2, outer = N ÷ 3)
colors = repeat([:red, :blue, :blue], outer = N ÷ 3)
scene = meshscatter!(p, mpos, markersize = sizes, color = colors)
indices = Int[]
for i in 1:3:N
push!(indices, i, i + 1, i, i + 2)
end
meshplot = p.plots[end] # meshplot is the last plot we added to p
# meshplot[1] -> the positions (first argument) converted to points, so
# we don't do the conversion 2 times for linesegments!
linesegments!(p, lift(x-> view(x, indices), meshplot[1]))
end
# To write out a video of the whole simulation
using Makie
result = do_simulation(...)
scene = plot(result)
record(scene, joinpath(homedir(), "Desktop", "slider.mp4"), 1:length(result.solution.t)) do i
scene[end][:simulation_index] = i
end
# or a slider example
scene = Scene()
# the whole layouting is still horrible - which is next on the todo list!
ui_scene = Scene(scene, lift(x-> IRect(0, 0, widths(x)[1], 50), pixelarea(scene)))
campixel!(ui_scene)
plot_scene = Scene(scene, lift(x-> IRect(0, 50, widths(x) .- Vec(0, 50)), pixelarea(scene)))
sim = plot!(plot_scene, result)[end]
sim_index = slider!(ui_scene, 1:length(result.solution.t), raw = true)[end]
foreach(sim_index[:value]) do idx
sim[:simulation_index] = idx
end
scene
#the above should soon become:
sim = plot(result)
slider = slider(1:N)
foreach(slider) do idx
sim[end][:simulation_index] = idx
end
hbox(sim, slider)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment