MakieOrg / Makie.jl

Interactive data visualizations and plotting in Julia
https://docs.makie.org/stable
MIT License
2.38k stars 302 forks source link

Can't provide multiple ranges to labelslidersgrid #813

Open pbouffard opened 3 years ago

pbouffard commented 3 years ago

A slight modification of the example from http://makie.juliaplots.org/dev/makielayout/layoutables_examples.html triggers the error:

julia> lsgrid = labelslidergrid!(scene,
           ["Voltage", "Current", "Resistance"],
           [Ref(LinRange(0:0.1:1000)), Ref(LinRange(0:0.1:1000)), Ref(LinRange(0:0.1:1000))];
           formats = [x -> "$(round(x, digits = 1))$s" for s in ["V", "A", "Ω"]],
           width = 350,
           tellheight = false)
ERROR: MethodError: no method matching -(::LinRange{Float64}, ::Int64)
For element-wise subtraction, use broadcasting with dot syntax: array .- scalar
Closest candidates are:
  -(::T, ::T) where T<:Union{Int128, Int16, Int32, Int64, Int8, UInt128, UInt16, UInt32, UInt64, UInt8} at int.jl:86
  -(::Rational, ::Integer) at rational.jl:288
  -(::Animations.Keyframe, ::Real) at /Users/patrick/.julia/packages/Animations/bSVbm/src/keyframes.jl:9
  ...
Stacktrace:
  [1] closest_index_inexact(sliderrange::Base.RefValue{LinRange{Float64}}, value::Int64)
    @ AbstractPlotting.MakieLayout ~/.julia/dev/AbstractPlotting/src/makielayout/layoutables/slider.jl:191
  [2] closest_index(sliderrange::Base.RefValue{LinRange{Float64}}, value::Int64)
    @ AbstractPlotting.MakieLayout ~/.julia/dev/AbstractPlotting/src/makielayout/layoutables/slider.jl:184
  [3] Slider(fig_or_scene::Scene; bbox::Nothing, kwargs::Base.Iterators.Pairs{Symbol, Base.RefValue{LinRange{Float64}}, Tuple{Symbol}, NamedTuple{(:range,), Tuple{Base.RefValue{LinRange{Float64}}}}})
    @ AbstractPlotting.MakieLayout ~/.julia/dev/AbstractPlotting/src/makielayout/layoutables/slider.jl:79
  [4] (::AbstractPlotting.MakieLayout.var"#98#102"{Dict{Any, Any}, Dict{Any, Any}, Dict{Any, Any}, Scene})(label::String, range::Base.RefValue{LinRange{Float64}}, format::Function)
    @ AbstractPlotting.MakieLayout ~/.julia/dev/AbstractPlotting/src/makielayout/helpers.jl:430
  [5] _broadcast_getindex_evalf
    @ ./broadcast.jl:648 [inlined]
  [6] _broadcast_getindex
    @ ./broadcast.jl:621 [inlined]
  [7] getindex
    @ ./broadcast.jl:575 [inlined]
  [8] macro expansion
    @ ./broadcast.jl:982 [inlined]
  [9] macro expansion
    @ ./simdloop.jl:77 [inlined]
 [10] copyto!
    @ ./broadcast.jl:981 [inlined]
 [11] copyto!
    @ ./broadcast.jl:936 [inlined]
 [12] copy
    @ ./broadcast.jl:908 [inlined]
 [13] materialize
    @ ./broadcast.jl:883 [inlined]
 [14] broadcast(::AbstractPlotting.MakieLayout.var"#98#102"{Dict{Any, Any}, Dict{Any, Any}, Dict{Any, Any}, Scene}, ::Vector{String}, ::Vector{Base.RefValue{LinRange{Float64}}}, ::Vector{var"#2#4"{String}})
    @ Base.Broadcast ./broadcast.jl:821
 [15] labelslidergrid!(scene::Scene, labels::Vector{String}, ranges::Vector{Base.RefValue{LinRange{Float64}}}; formats::Vector{var"#2#4"{String}}, sliderkw::Dict{Any, Any}, labelkw::Dict{Any, Any}, valuekw::Dict{Any, Any}, layoutkw::Base.Iterators.Pairs{Symbol, Integer, Tuple{Symbol, Symbol}, NamedTuple{(:width, :tellheight), Tuple{Int64, Bool}}})
    @ AbstractPlotting.MakieLayout ~/.julia/dev/AbstractPlotting/src/makielayout/helpers.jl:429
 [16] top-level scope
    @ REPL[5]:1
pbouffard commented 3 years ago

So actually it looks like the issue has to do with the Ref's:

julia> ranges = [LinRange(0:0.1:1000), LinRange(0:0.1:1000), LinRange(0:0.1:1000)]
3-element Vector{LinRange{Float64}}:
 range(0.0, stop=1000.0, length=10001)
 range(0.0, stop=1000.0, length=10001)
 range(0.0, stop=1000.0, length=10001)

julia> lsgrid = labelslidergrid!(scene,
                         ["Voltage", "Current", "Resistance"],
                         ranges;
                         formats = [x -> "$(round(x, digits = 1))$s" for s in ["V", "A", "Ω"]],
                         width = 350,
                         tellheight = false)

(sliders = Slider[Slider(), Slider(), Slider()], labels = Label[Label(), Label(), Label()], valuelabels = Label[Label(), Label(), Label()], layout = GridLayout[3, 3] (9 children))

julia> ranges = [0:0.1:1000, 0:0.1:1000, 0:0.1:1000]
3-element Vector{StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}}}:
 0.0:0.1:1000.0
 0.0:0.1:1000.0
 0.0:0.1:1000.0

julia> lsgrid = labelslidergrid!(scene,
                         ["Voltage", "Current", "Resistance"],
                         ranges;
                         formats = [x -> "$(round(x, digits = 1))$s" for s in ["V", "A", "Ω"]],
                         width = 350,
                         tellheight = false)
(sliders = Slider[Slider(), Slider(), Slider()], labels = Label[Label(), Label(), Label()], valuelabels = Label[Label(), Label(), Label()], layout = GridLayout[3, 3] (9 children))

julia> ranges = [Ref(0:0.1:1000), Ref(0:0.1:1000), Ref(0:0.1:1000)];

julia> lsgrid = labelslidergrid!(scene,
                         ["Voltage", "Current", "Resistance"],
                         ranges;
                         formats = [x -> "$(round(x, digits = 1))$s" for s in ["V", "A", "Ω"]],
                         width = 350,
                         tellheight = false)
ERROR: MethodError: no method matching -(::StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}}, ::Int64)
For element-wise subtraction, use broadcasting with dot syntax: array .- scalar
Closest candidates are:
  -(::T, ::T) where T<:Union{Int128, Int16, Int32, Int64, Int8, UInt128, UInt16, UInt32, UInt64, UInt8} at int.jl:86
  -(::Rational, ::Integer) at rational.jl:288
  -(::StepRangeLen{T, R, S}) where {T, R, S} at range.jl:943
  ...
Stacktrace:
  [1] closest_index_inexact(sliderrange::Base.RefValue{StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}}}, value::Int64)
    @ AbstractPlotting.MakieLayout ~/.julia/dev/AbstractPlotting/src/makielayout/layoutables/slider.jl:191
  [2] closest_index(sliderrange::Base.RefValue{StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}}}, value::Int64)
    @ AbstractPlotting.MakieLayout ~/.julia/dev/AbstractPlotting/src/makielayout/layoutables/slider.jl:184
  [3] Slider(fig_or_scene::Scene; bbox::Nothing, kwargs::Base.Iterators.Pairs{Symbol, Base.RefValue{StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}}}, Tuple{Symbol}, NamedTuple{(:range,), Tuple{Base.RefValue{StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}}}}}})
    @ AbstractPlotting.MakieLayout ~/.julia/dev/AbstractPlotting/src/makielayout/layoutables/slider.jl:79
  [4] (::AbstractPlotting.MakieLayout.var"#98#102"{Dict{Any, Any}, Dict{Any, Any}, Dict{Any, Any}, Scene})(label::String, range::Base.RefValue{StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}}}, format::Function)
    @ AbstractPlotting.MakieLayout ~/.julia/dev/AbstractPlotting/src/makielayout/helpers.jl:430
  [5] _broadcast_getindex_evalf
    @ ./broadcast.jl:648 [inlined]
  [6] _broadcast_getindex
    @ ./broadcast.jl:621 [inlined]
  [7] getindex
    @ ./broadcast.jl:575 [inlined]
  [8] macro expansion
    @ ./broadcast.jl:982 [inlined]
  [9] macro expansion
    @ ./simdloop.jl:77 [inlined]
 [10] copyto!
    @ ./broadcast.jl:981 [inlined]
 [11] copyto!
    @ ./broadcast.jl:936 [inlined]
 [12] copy
    @ ./broadcast.jl:908 [inlined]
 [13] materialize
    @ ./broadcast.jl:883 [inlined]
 [14] broadcast(::AbstractPlotting.MakieLayout.var"#98#102"{Dict{Any, Any}, Dict{Any, Any}, Dict{Any, Any}, Scene}, ::Vector{String}, ::Vector{Base.RefValue{StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}}}}, ::Vector{var"#22#24"{String}})
    @ Base.Broadcast ./broadcast.jl:821
 [15] labelslidergrid!(scene::Scene, labels::Vector{String}, ranges::Vector{Base.RefValue{StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}}}}; formats::Vector{var"#22#24"{String}}, sliderkw::Dict{Any, Any}, labelkw::Dict{Any, Any}, valuekw::Dict{Any, Any}, layoutkw::Base.Iterators.Pairs{Symbol, Integer, Tuple{Symbol, Symbol}, NamedTuple{(:width, :tellheight), Tuple{Int64, Bool}}})
    @ AbstractPlotting.MakieLayout ~/.julia/dev/AbstractPlotting/src/makielayout/helpers.jl:429
 [16] top-level scope
    @ REPL[16]:1

Maybe this then is an issue with the use of Ref and/or its interaction with broadcast within the method?

If so I guess this is not a Makie issue though I'm not sure if it's actually a bug or just not an appropriate mixture of Ref and broadcast. Regardless perhaps the labelslidergrid! examples should avoid using Ref, or include an example with more than one range where Ref isn't used.

jkrumbiegel commented 3 years ago

Wrapping an iterable with Ref is a standard method in Julia to use it as a scalar in a broadcasting expression. It says that's the purpose in the comment in the example as well, but maybe it's still a bit confusing?

ffreyer commented 3 weeks ago

Is this still a relevant issue?