Stream: helpdesk (published)

Topic: makie updating vline for slider value


view this post on Zulip KronosTheLate (May 11 2021 at 07:23):

Based heavily on the documentation, I have created the following code to interactivly explore some theoretical expressions. Non-relevant funfact is that R_load=R_cell should indicate the peak in load-power:

using GLMakie

fig = Figure()
ax = Axis(fig[1, 1])
ax.title="Current and power-output from a solar cell"

lsgrid = labelslidergrid!(
    fig,
    ["V cell", "R cell"],
    [0:0.1:10, 0:0.1:10];
    formats = [x -> "$(round(x, digits = 1))$s" for s in ["V", "Ω"]],
    tellwidth = false)
set_close_to!(lsgrid.sliders[1], 5)
set_close_to!(lsgrid.sliders[2], 1)

V_cell = lsgrid.sliders[1].value
R_cell = lsgrid.sliders[2].value

fig[2, 1] = lsgrid.layout

R_load = LinRange(0, 10, 100)

R_tot = @lift $R_cell .+ $R_load
i = @lift $V_cell ./ $R_tot
p_load = @lift $R_load .* $i.^2

lines!(ax, R_load, i, label="Current [A]", color=:red)
lines!(ax, R_load, p_load, label="Load power [P]", color=:black)

axislegend(location=(1, 1))
ylims!(ax, 0, 10)
ax.xlabel="Load resistance [Ω]"

.
This all works great - the sliders look good, and everything updates in a very satisfying way. The problem occurs when I try and add a simple vertical line indicating the value of one of the sliders. I define it in the exact same way as R_tot, i and p_load:

# Observable{Any} => Observable{Float64}, just in case:
# R_cell_float is then created just like the other values
R_cell_float = @lift $R_cell * 1

.
And from here, things go downhill. The following two attempts should work as far as I can tell, but throw different errors involving coversion-errors:

julia> vline!(ax, R_cell_float)
ERROR: Cannot convert Axis to series data for plotting

julia> vlines!(ax, [R_cell_float])
ERROR: MethodError: Cannot `convert` an object of type Observable{Vector{Float64}} to an object of type Float32

.
A two final attempts actually plot the desired line (Wheey!), but they do not at all respond to the slider - it is very static. The two attempts are:

lines!(ax, [R_cell_val, R_cell_val], [1, 9], linestyle=:dash)
vlines!(ax, [R_cell_float.val])

Do anyone know what I am doing wrong, and how one would simply display the current value of one of the sliders as a vertical line?

view this post on Zulip KronosTheLate (May 11 2021 at 10:30):

I figured it out! Even through the examples over at https://makie.juliaplots.org/stable/makielayout/axis.html#Vertical-/-Horizontal-Lines give the values at which one wants lines as vectors, the problem was fixed by passing them directly. So passing the line value as Observable{Float64}, or Observable{Vector{Float64}} both work, whereas Vector{Observable{Float64}}does not.

For completeness, a full working example follows:

using GLMakie

fig = Figure()
ax = Axis(fig[1, 1])
ylims!(ax, 0.1, 10)
ax.yscale = log

ax.title = "Current and power-output from a solar cell"

lsgrid = labelslidergrid!(
    fig,
    ["V cell", "R cell"],
    [0:0.1:10, 0:0.1:10];
    formats = [x -> "$(round(x, digits = 1))$s" for s in ["V", "Ω"]],
    tellwidth = false)
set_close_to!(lsgrid.sliders[1], 5)
set_close_to!(lsgrid.sliders[2], 2)

V_cell = lsgrid.sliders[1].value
R_cell = lsgrid.sliders[2].value

fig[2, 1] = lsgrid.layout

R_load = LinRange(0.1, 10, 100)

R_tot = @lift $R_cell .+ $R_load
i = @lift $V_cell ./ $R_tot
p_load = @lift $R_load .* $i.^2

p_load_max = @lift maximum($p_load)
R_cell_float = @lift $R_cell * 1

lines!(ax, R_load, i, label="Current [A]", color=:red)
lines!(ax, R_load, p_load, label="Load power [W]", color=:black)

axislegend(location=(1, 1))
ax.xlabel="Load resistance [Ω]"

vlines!(ax, R_cell_float, linestyle=:dash)
hlines!(ax, p_load_max, linestyle=:dash)

fig

view this post on Zulip KronosTheLate (May 11 2021 at 11:00):

Even through I realize I am just talking to myself in public, I like completeness. So here is the GitHub issue with a proper writeup of the problem as I see it: https://github.com/JuliaPlots/Makie.jl/issues/946


Last updated: Oct 02 2023 at 04:34 UTC