GLMakie beginners help: Multiple sliders and an arrow

I wasn’t 100% sure what you asked for, but I crafted something anyways (based on the tutorial link you gave above):

using GLMakie
GLMakie.activate!()

################################################################################
# Sliders
################################################################################

# initialize plot

fig = Figure(resolution = (3840, 2160))

# add axis

ax1 = fig[1, 1] = Axis(fig,
    # borders
    aspect = 1,
    # title
    title = "Sliders Tutorial",
    titlegap = 48, titlesize = 60,
    # x-axis
    xautolimitmargin = (0, 0), xgridwidth = 2, xticklabelsize = 36,
    xticks = LinearTicks(20), xticksize = 18,
    # y-axis
    yautolimitmargin = (0, 0), ygridwidth = 2, yticklabelpad = 14,
    yticklabelsize = 36, yticks = LinearTicks(20), yticksize = 18
)

# darken axes

vlines!(ax1, [0], linewidth = 2)
hlines!(ax1, [0], linewidth = 2)

# create sliders

lsgrid = labelslidergrid!(fig,
    ["scale", "x-reference", "y-reference"], #edited from original
    Ref(LinRange(-10:0.01:10));
    formats = [x -> "$(round(x, digits = 2))"],
    labelkw = Dict([(:textsize, 30)]),
    sliderkw = Dict([(:linewidth, 24)]),
    valuekw = Dict([(:textsize, 30)])
)

# set starting position for slope

set_close_to!(lsgrid.sliders[1], 1.0)

# layout sliders

sl_sublayout = GridLayout(height = 150)
fig[2, 1] = sl_sublayout
fig[2, 1] = lsgrid.layout

# draw a function

x = -10:0.01:10
m = @lift($scale .* x.^2) #quadratic function #edited from original
line1 = lines!(ax1, x, m, color = :blue, linewidth = 5) #edited from original

# create listeners

scale = lsgrid.sliders[1].value #edited from original
xreference = lsgrid.sliders[2].value #edited from original
yreference  = lsgrid.sliders[3].value #added 

# xreference, yreference are Float32s
# but for arrows! below we need vectors of Float32s, so we promote them here

# arrow base points
xbase = @lift([$xreference])
ybase = @lift([$yreference])

#new multi-variable scalar-valued functions
p(x,y,scale) = (x + scale * y-1)^2/(scale^2) #added
z(x,y,scale) = cbrt(-p(x,y,scale)/2) #added

# arrow head points
# note: here we also return vectors
xhead = lift(xreference, yreference, scale) do x, y, s
    return [ x/1 + 2*s * z(x,y,s) ]
end
yhead = lift(xreference, yreference, scale) do x, y, s
    return [ y + z(x,y,s) ]
end

arrows!(ax1, xbase, ybase, xhead, yhead)

display(fig)

The above gives you now the arrow you can control with the sliders. Maybe you need to tune the computation of the end points a bit, because right now it does not seem to make any sense to me :laughing:

Modifications I made to your code:

  • You can’t use - in variable names, so I renamed x-reference to xreference, etc.
  • I replaced :fontsize with :textsize, because that was changed recently, but you might be running an older version of Makie.
  • Arrows can be drawn with arrows, cf. arrows - Beautiful Makie. For this to work, one has to pass Vector{Float32} (or Observables thereof) to arrows!. Hence, I add an extra lift for that to promote the xreference, yreference. The reason it wants a Vector instead of a single number for each component is that arrows is optimized to draw vector fields, see the link above.

Last remark: Next time please provide a minimal working example (MWE) of the code that is already working and others can then use to build on top off.

2 Likes