GiovineItalia / Gadfly.jl

Crafty statistical graphics for Julia.
http://gadflyjl.org/stable/
Other
1.9k stars 250 forks source link

Incompatibility with JuliaImage ImageCore.jl #1466

Closed NicholasWMRitchie closed 1 week ago

NicholasWMRitchie commented 4 years ago

Gadfly fails when manual_color_key(...) is used when ImageCore is loaded

using Gadfly
using Colors

curves = 1:3

const palette = distinguishable_colors(
    length(curves)+3,
    [ RGB(253 / 255, 253 / 255, 241 / 255), RGB(0, 0, 0), colorant"DodgerBlue4"],
    transform = deuteranopic,
)[3:end]

ls = [layer(x=1:10, y=map(x->x^i, 1:10), Geom.line, Theme(default_color = palette[i] )) for i in curves ]
# Succeeds
plot(ls..., Guide.manual_color_key("Curves", [ "Curve $i" for i in curves ], palette[curves]))

using ImageCore
# Fails on the second plot...
plot(ls..., Guide.manual_color_key("Curves", [ "Curve $i" for i in curves ], palette[curves]))

The problem is the line in ImageCore/convert_reinterpret.jl line 80-83

function Base.convert(::Type{Array{Cdest,n}},
                      img::AbstractArray{Csrc,n}) where {Cdest<:Colorant,n,Csrc<:Colorant}
    copyto!(Array{ccolor(Cdest, Csrc)}(undef, size(img)), img)
end

This leads to this error:

ERROR: LoadError: TypeError: in new, expected Array{Colorant,1}, got a value of type Array{RGB{Float64},1}
Stacktrace:
 [1] ManualDiscreteKey at C:\Users\nritchie\.julia\dev\Gadfly\src\guide\keys.jl:267 [inlined]
 [2] Gadfly.Guide.ManualDiscreteKey(; title::String, labels::Array{String,1}, pos::Array{Any,1}, color::Array{RGB{Float64},1}, shape::Array{Function,1}, size::Array{Measures.Measure,1}) at C:\Users\nritchie\.julia\dev\Gadfly\src\guide\keys.jl:295
 [3] #manual_color_key#131 at C:\Users\nritchie\.julia\dev\Gadfly\src\guide\keys.jl:321 [inlined]
 [4] manual_color_key(::String, ::Array{String,1}, ::Array{RGB{Float64},1}) at C:\Users\nritchie\.julia\dev\Gadfly\src\guide\keys.jl:321
 [5] top-level scope at c:\users\nritchie\.julia\dev\NeXLDatabase\weave\testgadfly.jl:18
 [6] include(::String) at .\client.jl:457
 [7] top-level scope at REPL[1]:1
in expression starting at c:\users\nritchie\.julia\dev\NeXLDatabase\weave\testgadfly.jl:18

Is this a Gadfly bug or an ImageCore bug? Or just an unfortunate interaction.

NicholasWMRitchie commented 4 years ago

Changing the type of the field colors in ManualDiscreteKey from Vector{Colorant} to Vector{<:Colorant} resolves the problem. However, this brings up two questions:

  1. Is there a better/more elegant fix?
  2. Are there other places in Gadfly susceptible to this issue?
NicholasWMRitchie commented 4 years ago

Hopefully, this pull in ImageCore will fix the problem.

Mattriks commented 4 years ago

@NicholasWMRitchie Great that you have found the source of the issue! This issue (also #1454) does seem to relate to another package unnecessarily overloading Base.convert, since things work as expected in Gadfly, as in your post.

NicholasWMRitchie commented 4 years ago

It's back!!! It seems that recent changes to ImageCore.jl has broken ManualDiscreteKey (manual_discrete_key(....) and manual_color_key(...)) again. The key line is convert(::Type{Array{ColorTypes.Color,N} where N}, ::Array{ColorTypes.Color,1})@deprecations.jl:62 which is in ImageCore.jl and seems to be one of these dreaded invalidations.

Failed to show value:

MethodError: no method matching ColorTypes.Color(::ColorTypes.RGB{FixedPointNumbers.Normed{UInt8,8}})

_broadcast_getindex_evalf@broadcast.jl:648[inlined]
_broadcast_getindex@broadcast.jl:621[inlined]
getindex@broadcast.jl:575[inlined]
copy@broadcast.jl:876[inlined]
materialize@broadcast.jl:837[inlined]
convert(::Type{Array{ColorTypes.Color,N} where N}, ::Array{ColorTypes.Color,1})@deprecations.jl:62
cat_aes_var!(::IndirectArrays.IndirectArray{ColorTypes.Color,1,Array{Int64,1},Array{ColorTypes.Color,1}}, ::IndirectArrays.IndirectArray{ColorTypes.Color,1,Array{Int64,1},Array{ColorTypes.Color,1}})@aesthetics.jl:300
concat(::Gadfly.Aesthetics, ::Vararg{Gadfly.Aesthetics,N} where N)@aesthetics.jl:250
render_prepare(::Gadfly.Plot)@Gadfly.jl:685
render(::Gadfly.Plot)@Gadfly.jl:740
draw@Gadfly.jl:847[inlined]
show(::IOContext{Base.GenericIOBuffer{Array{UInt8,1}}}, ::MIME{Symbol("text/html")}, ::Gadfly.Plot)@Gadfly.jl:937
#show_richest#18(::Bool, ::typeof(Main.PlutoRunner.show_richest), ::IOContext{Base.GenericIOBuffer{Array{UInt8,1}}}, ::Any)@PlutoRunner.jl:382
show_richest(::IOContext{Base.GenericIOBuffer{Array{UInt8,1}}}, ::Any)@PlutoRunner.jl:330
#sprint_withreturned#17(::IOContext{Base.PipeEndpoint}, ::Int64, ::typeof(Main.PlutoRunner.sprint_withreturned), ::Function, ::Gadfly.Plot)@PlutoRunner.jl:302
format_output(::Any)@PlutoRunner.jl:242
formatted_result_of(::Base.UUID, ::Bool)@PlutoRunner.jl:53
top-level scope@none:1

I've also submitted this as https://github.com/JuliaImages/ImageCore.jl/issues/150

NicholasWMRitchie commented 1 week ago

The problem seems to be resolved.