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?
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
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: Nov 22 2024 at 04:41 UTC