diff --git a/Project.toml b/Project.toml index fde8b2c..0698ea8 100644 --- a/Project.toml +++ b/Project.toml @@ -1,6 +1,6 @@ name = "PlotUtils" uuid = "995b91a9-d308-5afd-9ec6-746e21dbc043" -version = "1.3.3" +version = "1.3.4" [deps] ColorSchemes = "35d6a980-a343-548e-a6ea-1d62b119f2f4" diff --git a/src/colorschemes.jl b/src/colorschemes.jl index 4fb0c60..9e80254 100644 --- a/src/colorschemes.jl +++ b/src/colorschemes.jl @@ -51,6 +51,17 @@ plot_color(cg::ContinuousColorGradient, α::Number) = Base.show(io::IO, m::MIME"image/svg+xml", cg::ContinuousColorGradient) = show(io, m, cg[get_range(100)]) +function sample_color(cg::ContinuousColorGradient, x::AbstractFloat) + c, v = cg.colors, cg.values + if (index = findfirst(==(x), v)) === nothing + nm1 = length(v) - 1 + i = min(nm1, findlast(<(x), v)) + r = (x - v[i]) / (v[i + 1] - v[i]) + index = (i + r - 1) / nm1 + end + c[index] +end + function Base.get(cg::ContinuousColorGradient, x::AbstractFloat, rangescale = (0.0, 1.0)) isfinite(x) || return invisible() rangescale = get_rangescale(rangescale) @@ -59,7 +70,7 @@ function Base.get(cg::ContinuousColorGradient, x::AbstractFloat, rangescale = (0 if rangescale != (0.0, 1.0) x = ColorSchemes.remap(x, rangescale..., 0, 1) end - get(cg.colors, x) + sample_color(cg, x) # specialize for x (boxing issues ?) end Base.reverse(cg::ContinuousColorGradient) = @@ -70,10 +81,10 @@ function ColorSchemes.getinverse(cg::ContinuousColorGradient, c) alpha(c) == 0 && return NaN z = getinverse(to_rgb(get_colorscheme(cg)), to_rgb(c)) cr = get_range(cg.colors) - if z in cr - cg.values[findfirst(==(z), cr)] + if (index = findfirst(==(z), cr)) !== nothing + cg.values[index] else - i = findlast(<(z), cr) + i = min(length(cr) - 1, findlast(<(z), cr)) ColorSchemes.remap(z, cr[i], cr[i + 1], cg.values[i], cg.values[i + 1]) end end diff --git a/test/runtests.jl b/test/runtests.jl index ae62321..ccc9a3f 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -30,7 +30,7 @@ const C0 = RGBA{PlotUtils.Colors.N0f8} @test plot_color(grad) === grad # JuliaPlots/Plots.jl/issues/4270 - @test get(grad, BigFloat(1), (-0.00033546262790251185, 1.0)) isa RGBA{BigFloat} + @test get(grad, BigFloat(1), (-0.0003354626279, 1.0)) isa RGBA{BigFloat} grad = cgrad([:red, "blue"]) @test color_list(grad) == C[colorant"red", colorant"blue"] @@ -75,8 +75,25 @@ end @testset "gradients" begin grad = cgrad(:inferno) @test length(grad) == 256 - @test RGB(grad.colors[1]) == RGB(0.001462, 0.000466, 0.013866) - @test RGB(grad.colors[end]) == RGB(0.988362, 0.998364, 0.644924) + @test RGB(grad.colors[1]) ≈ RGB(0.001462, 0.000466, 0.013866) + @test RGB(grad.colors[end]) ≈ RGB(0.988362, 0.998364, 0.644924) +end + +@testset "sampling" begin + # github.com/MakieOrg/Makie.jl/issues/2635 + cmap = cgrad([:black, :white, :orange], [0, 0.2, 1]) + # sample ouside the given values + @test RGB(get(cmap, 0.15)) ≈ RGB(0.75, 0.75, 0.75) + @test RGB(get(cmap, 0.5)) ≈ RGB(1.0, 0.86764705, 0.625) + @test RGB(get(cmap, 0.8)) ≈ RGB(1.0, 0.73529411, 0.25) +end + +@testset "reverse" begin + cmap = reverse(cgrad([:black, :white, :orange], [0, 0.2, 1])) + # sample ouside the given values + @test RGB(get(cmap, 0.15)) ≈ RGB(1.0, 0.71323529, 0.1875) + @test RGB(get(cmap, 0.5)) ≈ RGB(1.0, 0.86764705, 0.625) + @test RGB(get(cmap, 0.75)) ≈ RGB(1.0, 0.97794117, 0.9375) end # ----------------------