MakieOrg / Makie.jl

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

`StackOverflowError` when passing tuple (instead of a color type) for `colormap` #1297

Open goretkin opened 3 years ago

goretkin commented 3 years ago
using Makie: Makie, RGBA
using CairoMakie: CairoMakie
Makie.heatmap(rand(Bool, 10, 10); colormap=[(0, 0, 0, 0), (0, 0, 0, 1)])
# instead of Makie.heatmap(rand(Bool, 10, 10); colormap=[RGBA(0, 0, 0, 0), RGBA(0, 0, 0, 1)])

causes a stack overflow (and sometimes a segfault)

julia> Makie.save("/tmp/out.pdf", Makie.current_figure())
ERROR: StackOverflowError:
Stacktrace:
     [1] Array
       @ ./boot.jl:448 [inlined]
     [2] Array
       @ ./boot.jl:457 [inlined]
     [3] Array
       @ ./boot.jl:465 [inlined]
     [4] similar
       @ ./abstractarray.jl:785 [inlined]
     [5] similar
       @ ./abstractarray.jl:784 [inlined]
     [6] similar
       @ ./broadcast.jl:197 [inlined]
     [7] similar
       @ ./broadcast.jl:196 [inlined]
     [8] copy
       @ ./broadcast.jl:908 [inlined]
     [9] materialize
       @ ./broadcast.jl:883 [inlined]
    [10] convert_attribute(cm::Vector{NTuple{4, Int64}}, ::Makie.Key{:colormap}, n::Int64)
       @ Makie ~/.julia/packages/Makie/c5WJV/src/conversions.jl:1024
    [11] to_colormap(x::Vector{NTuple{4, Int64}}, n::Int64)
       @ Makie ~/.julia/packages/Makie/c5WJV/src/conversions.jl:1046
--- the last 2 lines are repeated 39988 more times ---
 [79988] convert_attribute(cm::Vector{NTuple{4, Int64}}, ::Makie.Key{:colormap}, n::Int64)
       @ Makie ~/.julia/packages/Makie/c5WJV/src/conversions.jl:1024
  [13f3f980] CairoMakie v0.5.10
  [ee78f7c6] Makie v0.13.14
goretkin commented 3 years ago

with the latest versions, I can only ever get a segfault (which I think is a problem with macOS. other platforms will probably throw StackOverflowError without the process crashing)

  [13f3f980] CairoMakie v0.6.5
  [ee78f7c6] Makie v0.15.2
timholy commented 2 years ago

I haven't looked at the code, but a good trick to prevent stack overflows is something like

foo(x::T) = ...
foo(x) = foo(convert(T, x)::T)

The convert(T, x)::T ensures if you don't get a T out, you get an immediate error rather than foo(x) endlessly calling itself.

ffreyer commented 3 months ago

This could be fixed by adding the relevant methods for `Makie.to_color()

ffreyer commented 2 weeks ago

The functions for it are here: https://github.com/MakieOrg/Makie.jl/blob/2b5931ee92c00603a669d02b8103bff49315024b/src/conversions.jl#L908-L919