Strange plotting problem with Makie figures

I get a stack overflow when I try to manipulate Makie figures. This happens in multiple use cases. I don’t know the source of the problem from the stack trace. This happens when I try to just show the figure or display it.

infil> fig
Error showing value of type Figure:
ERROR: StackOverflowError:
Stacktrace:
[1] data_limits(plot::Plot{lineplot, Tuple{Hyperplane{2, 3}}})
@ Makie ~/.julia/packages/Makie/tjqse/src/layouting/data_limits.jl:45
[2] point_iterator(plot::Plot{lineplot, Tuple{Hyperplane{2, 3}}})
@ Makie ~/.julia/packages/Makie/tjqse/src/layouting/data_limits.jl:178
— the last 2 lines are repeated 39044 more times —
[78091] data_limits(plot::Plot{lineplot, Tuple{Hyperplane{2, 3}}})
@ Makie ~/.julia/packages/Makie/tjqse/src/layouting/data_limits.jl:45
[78092] boundingbox(plot::Plot{lineplot, Tuple{Hyperplane{2, 3}}}, space::Symbol)
@ Makie ~/.julia/packages/Makie/tjqse/src/layouting/boundingbox.jl:38
[78093] (::Makie.var"#1044#1046"{Makie.var"#exclude#1739"{Int64}, Symbol, Base.RefValue{GeometryBasics.HyperRectangle{…}}})(plot::Plot{lineplot, Tuple{Hyperplane{…}}})
@ Makie ~/.julia/packages/Makie/tjqse/src/layouting/boundingbox.jl:21
[78094] foreach(f::Makie.var"#1044#1046"{Makie.var"#exclude#1739"{Int64}, Symbol, Base.RefValue{GeometryBasics.HyperRectangle{3, Float64}}}, itr::Vector{Plot})
@ Base ./abstractarray.jl:3098
[78095] foreach_plot
@ ~/.julia/packages/Makie/tjqse/src/layouting/data_limits.jl:272 [inlined]
[78096] foreach_plot
@ ~/.julia/packages/Makie/tjqse/src/layouting/data_limits.jl:269 [inlined]
[78097] boundingbox
@ ~/.julia/packages/Makie/tjqse/src/layouting/boundingbox.jl:19 [inlined]
[78098] boundingbox
@ ~/.julia/packages/Makie/tjqse/src/layouting/boundingbox.jl:18 [inlined]
[78099] getlimits(la::Axis, dim::Int64)
@ Makie ~/.julia/packages/Makie/tjqse/src/makielayout/blocks/axis.jl:852
[78100] autolimits(ax::Axis, dim::Int64)
@ Makie ~/.julia/packages/Makie/tjqse/src/makielayout/blocks/axis.jl:940
[78101] xautolimits
@ ~/.julia/packages/Makie/tjqse/src/makielayout/blocks/axis.jl:971 [inlined]
[78102] reset_limits!(ax::Axis; xauto::Bool, yauto::Bool, zauto::Bool)
@ Makie ~/.julia/packages/Makie/tjqse/src/makielayout/blocks/axis.jl:571
[78103] reset_limits!
@ ~/.julia/packages/Makie/tjqse/src/makielayout/blocks/axis.jl:558 [inlined]
[78104] update_state_before_display!(ax::Axis)
@ Makie ~/.julia/packages/Makie/tjqse/src/figureplotting.jl:403
[78105] update_state_before_display!(f::Figure)
@ Makie ~/.julia/packages/Makie/tjqse/src/figureplotting.jl:275
[78106] display(figlike::Figure; backend::Module, inline::Bool, update::Bool, screen_config::@Kwargs{})
@ Makie ~/.julia/packages/Makie/tjqse/src/display.jl:164
[78107] display(figlike::Figure)
@ Makie ~/.julia/packages/Makie/tjqse/src/display.jl:130
[78108] #invokelatest#2
@ ./essentials.jl:892 [inlined]
[78109] invokelatest
@ ./essentials.jl:889 [inlined]
[78110] print_response(errio::IO, response::Any, show_value::Bool, have_color::Bool, specialdisplay::Union{Nothing, AbstractDisplay})
@ REPL ~/.julia/juliaup/julia-1.10.7+0.x64.linux.gnu/share/julia/stdlib/v1.10/REPL/src/REPL.jl:315
[78111] (::REPL.var"#57#58"{REPL.LineEditREPL, Tuple{Figure, Bool}, Bool, Bool})(io::Any)
@ REPL ~/.julia/juliaup/julia-1.10.7+0.x64.linux.gnu/share/julia/stdlib/v1.10/REPL/src/REPL.jl:284
[78112] with_repl_linfo(f::Any, repl::REPL.LineEditREPL)
@ REPL ~/.julia/juliaup/julia-1.10.7+0.x64.linux.gnu/share/julia/stdlib/v1.10/REPL/src/REPL.jl:569
[78113] print_response
@ ~/.julia/juliaup/julia-1.10.7+0.x64.linux.gnu/share/julia/stdlib/v1.10/REPL/src/REPL.jl:282 [inlined]
[78114] (::Infiltrator.var"#33#37"{…})(s::REPL.LineEdit.MIState, buf::IOBuffer, ok::Bool)
@ Infiltrator ~/.julia/packages/Infiltrator/uvPvr/src/Infiltrator.jl:718
[78115] #invokelatest#2
@ ./essentials.jl:892 [inlined]
[78116] invokelatest
@ ./essentials.jl:889 [inlined]
[78117] run_interface(terminal::REPL.Terminals.TextTerminal, m::REPL.LineEdit.ModalInterface, s::REPL.LineEdit.MIState)
@ REPL.LineEdit ~/.julia/juliaup/julia-1.10.7+0.x64.linux.gnu/share/julia/stdlib/v1.10/REPL/src/LineEdit.jl:2656
[78118] run_interface
@ ~/.julia/juliaup/julia-1.10.7+0.x64.linux.gnu/share/julia/stdlib/v1.10/REPL/src/LineEdit.jl:2650 [inlined]
[78119] debugprompt(mod::Module, locals::Dict{…}, trace::Vector{…}, terminal::REPL.Terminals.TTYTerminal, repl::REPL.LineEditREPL, ex::Nothing, bt::Nothing; nostack::Bool, file::String, fileline::Int64)
@ Infiltrator ~/.julia/packages/Infiltrator/uvPvr/src/Infiltrator.jl:739
[78120] start_prompt(mod::Module, locals::Dict{Symbol, Any}, file::String, fileline::Int64, ex::Nothing, bt::Nothing; terminal::Nothing, repl::Nothing, nostack::Bool)
@ Infiltrator ~/.julia/packages/Infiltrator/uvPvr/src/Infiltrator.jl:400
[78121] start_prompt(mod::Module, locals::Dict{Symbol, Any}, file::String, fileline::Int64, ex::Nothing, bt::Nothing)
@ Infiltrator ~/.julia/packages/Infiltrator/uvPvr/src/Infiltrator.jl:300
[78122] start_prompt
@ ~/.julia/packages/Infiltrator/uvPvr/src/Infiltrator.jl:300 [inlined]
[78123] macro expansion
@ ~/.julia/packages/Infiltrator/uvPvr/src/Infiltrator.jl:68 [inlined]
[78124] find_line(; mestimator::L2, num_samples::Int64, σ::Quantity{Float64, 𝐋, Unitful.FreeUnits{(px,), 𝐋, nothing}}, ϵ::Float64)
@ VisualGeometryToolkit ~/src/vgtk/src/euclidean/examples/lines.jl:5
[78125] find_line()
@ VisualGeometryToolkit ~/src/vgtk/src/euclidean/examples/lines.jl:1
[78126] top-level scope
@ REPL[6]:1
Some type information was truncated. Use show(err) to see complete types.

Hi there! You are more likely to get good help if you can provide a small piece of code that reproduces the problem that others can run. (see Please read: make it easier to help you)

Here’s a guess based on your output: the infil> prompt suggests that you are trying to display a figure while in Infiltrator.jl debug mode. Can you try running the code while not in debug?

1 Like

I’m unsuccessfully trying to use Makie recipes. Here is a simple example.

using Makie, StaticArrays

const VectorNd{N} = SVector{N,Float64} 
const Vector2d = VectorNd{2}
const Vector3d = VectorNd{3}

homogenize(x::SVector) = push(x,one(eltype(x)))

struct Hyperplane{M,N} <: StaticVector{N, Float64}
    v::VectorNd{N}

    Hyperplane(v::VectorNd{N}) where N = new{N-1,N}(v / norm(v[1:N-1]))
    Hyperplane{M,N}(v::VectorNd{N}) where {M,N} = M+1 == N ? new{M,N}(v / norm(v[1:N-1])) : throw("Dimension Error")
end

@inline Base.getindex(p::Hyperplane{N}, i::Int) where N = getindex(p.v, i)
@inline Tuple(p::Hyperplane{N}) where N = p.v

const Line2 = Hyperplane{2,3}

Line2(a::Float64, b::Float64, c::Float64) = Line2(SVector{3}(a,b,c))
Line2(ρ::Float64, θ::Float64) = Line2(Vector3d(-sin(θ),cos(θ),-ustrip(ρ)))

function Line2(p::Vector2d, q::Vector2d)
    v = q-p
    n = -l2normalize(SVector{2}(-v[2],v[1]))
    Line2(n..., dot(n,p))
end
    
function Base.getproperty(obj::Line2, sym::Symbol)
    if sym == :ρ
        return -obj[3]
    elseif sym == :θ
        return atan(obj[2], obj[1])
    elseif sym == :slope
        return -obj[1]/obj[2]
    elseif sym == :intercept
        return -obj[3]/obj[2]
    else
        return getfield(obj, sym)
    end
end

@recipe(LinePlot) do scene
    Attributes(
        color = :orange,
        linestyle = :dash,
        linewidth = 3,
    )
end

function Makie.plot!(p::LinePlot{<:Tuple{<:Line2}})
    line = p[1][]
    ablines(line.intercept, line.slope, color=p[:color][])
end

fig,_,_ = lineplot(Line2(0.0,1.0,-5.0))
display(fig)

In the code below, I have removed the line @inline Tuple(p::Hyperplane{N}) where N = p.v, which caused a different error, and I have rewritten the Makie.plot! function to act in place on the plot type, and I’ve added using LinearAlgebra (which is necessary to get the norm function. The code now works, although I can’t tell if it does what you would like it to.

using GLMakie, StaticArrays, LinearAlgebra

const VectorNd{N} = SVector{N,Float64} 
const Vector2d = VectorNd{2}
const Vector3d = VectorNd{3}

struct Hyperplane{M,N} <: StaticVector{N, Float64}
    v::VectorNd{N}

    Hyperplane(v::VectorNd{N}) where N = new{N-1,N}(v / norm(v[1:N-1]))
    Hyperplane{M,N}(v::VectorNd{N}) where {M,N} = M+1 == N ? new{M,N}(v / norm(v[1:N-1])) : throw("Dimension Error")
end

@inline Base.getindex(p::Hyperplane{N}, i::Int) where N = getindex(p.v, i)

const Line2 = Hyperplane{2,3}

Line2(a::Float64, b::Float64, c::Float64) = Line2(SVector{3}(a,b,c))
Line2(ρ::Float64, θ::Float64) = Line2(Vector3d(-sin(θ),cos(θ),-ustrip(ρ)))

function Line2(p::Vector2d, q::Vector2d)
    v = q-p
    n = -l2normalize(SVector{2}(-v[2],v[1]))
    Line2(n..., dot(n,p))
end
    
function Base.getproperty(obj::Line2, sym::Symbol)
    if sym == :ρ
        return -obj[3]
    elseif sym == :θ
        return atan(obj[2], obj[1])
    elseif sym == :slope
        return -obj[1]/obj[2]
    elseif sym == :intercept
        return -obj[3]/obj[2]
    else
        return getfield(obj, sym)
    end
end

@recipe(LinePlot) do scene
    Attributes(
        color = :orange,
        linestyle = :dash,
        linewidth = 3,
    )
end

function Makie.plot!(p::LinePlot{<:Tuple{<:Line2}})
    line = p[1][]
    ablines!(p, line.intercept, line.slope, color=p[:color][])
    p
end

fig,_,_ = lineplot(Line2(0.0,1.0,-5.0))
display(fig)