Here’s what I’ve figured out.
I can make a nice collection of colors
using Colors, ColorSchemes, RectiGrids, AxisKeys, GLMakie, Makie, Statistics, ImageShow
GLMakie.activate!(;scalefactor=2)
MYCOLORS = map(grid(a=range(-100,100; length=8),b=range(-100,100; length=8), L=round.(Int, range(0,100; length=6)))) do (;L,a,b)
Lab(L,a,b)
end
let fig = Figure(), colors = MYCOLORS
Label(fig[1,1]; text="Colors", tellwidth=false)
box = (fig[2,1])
foreach(pairs(axiskeys(colors,3))) do (iL,L)
ax = Axis(box[fldmod1(iL, 3)...]; title="L=$L", xlabel="a", ylabel="b")
heatmap!(ax, axiskeys(colors, 2), axiskeys(colors, 3), colors[:,:, iL])
end
fig
end
And I can measure the mean relative luminance of each one against all of the colors in viridis.
luminance(c) = XYZ(c).y
map(MYCOLORS) do c
mean(ColorSchemes.viridis.colors) do v
r = luminance(c)/luminance(v)
max(r,inv(r))
end
end
3-dimensional KeyedArray(NamedDimsArray(...)) with keys:
↓ a ∈ 8-element StepRangeLen{Float64,...}
→ b ∈ 8-element StepRangeLen{Float64,...}
◪ L ∈ 6-element Vector{Int64}
And data, 8×8×6 Array{Float64, 3}:
[:, :, 1] ~ (:, :, 0):
(-100.0) (-71.4286) (-42.8571) (-14.2857) (14.2857) (42.8571) (71.4286) (100.0)
(-100.0) Inf Inf Inf Inf Inf Inf Inf Inf
(-71.4286) Inf Inf Inf Inf Inf Inf Inf Inf
(-42.8571) Inf Inf Inf Inf Inf Inf Inf Inf
(-14.2857) Inf Inf Inf Inf Inf Inf Inf Inf
(14.2857) Inf Inf Inf Inf Inf Inf Inf Inf
(42.8571) Inf Inf Inf Inf Inf Inf Inf Inf
(71.4286) Inf Inf Inf Inf Inf Inf Inf Inf
(100.0) Inf Inf Inf Inf Inf Inf Inf Inf
[:, :, 2] ~ (:, :, 20):
(-100.0) (-71.4286) (-42.8571) (-14.2857) (14.2857) (42.8571) (71.4286) (100.0)
(-100.0) 9.48118 9.48118 9.48118 9.48118 9.48118 9.48118 9.48118 9.48118
(-71.4286) 9.48118 9.48118 9.48118 9.48118 9.48118 9.48118 9.48118 9.48118
(-42.8571) 9.48118 9.48118 9.48118 9.48118 9.48118 9.48118 9.48118 9.48118
(-14.2857) 9.48118 9.48118 9.48118 9.48118 9.48118 9.48118 9.48118 9.48118
(14.2857) 9.48118 9.48118 9.48118 9.48118 9.48118 9.48118 9.48118 9.48118
(42.8571) 9.48118 9.48118 9.48118 9.48118 9.48118 9.48118 9.48118 9.48118
(71.4286) 9.48118 9.48118 9.48118 9.48118 9.48118 9.48118 9.48118 9.48118
(100.0) 9.48118 9.48118 9.48118 9.48118 9.48118 9.48118 9.48118 9.48118
[:, :, 3] ~ (:, :, 40):
(-100.0) (-71.4286) (-42.8571) (-14.2857) (14.2857) (42.8571) (71.4286) (100.0)
(-100.0) 3.12448 3.12448 3.12448 3.12448 3.12448 3.12448 3.12448 3.12448
(-71.4286) 3.12448 3.12448 3.12448 3.12448 3.12448 3.12448 3.12448 3.12448
(-42.8571) 3.12448 3.12448 3.12448 3.12448 3.12448 3.12448 3.12448 3.12448
(-14.2857) 3.12448 3.12448 3.12448 3.12448 3.12448 3.12448 3.12448 3.12448
(14.2857) 3.12448 3.12448 3.12448 3.12448 3.12448 3.12448 3.12448 3.12448
(42.8571) 3.12448 3.12448 3.12448 3.12448 3.12448 3.12448 3.12448 3.12448
(71.4286) 3.12448 3.12448 3.12448 3.12448 3.12448 3.12448 3.12448 3.12448
(100.0) 3.12448 3.12448 3.12448 3.12448 3.12448 3.12448 3.12448 3.12448
[:, :, 4] ~ (:, :, 60):
(-100.0) (-71.4286) (-42.8571) (-14.2857) (14.2857) (42.8571) (71.4286) (100.0)
(-100.0) 3.12086 3.12086 3.12086 3.12086 3.12086 3.12086 3.12086 3.12086
(-71.4286) 3.12086 3.12086 3.12086 3.12086 3.12086 3.12086 3.12086 3.12086
(-42.8571) 3.12086 3.12086 3.12086 3.12086 3.12086 3.12086 3.12086 3.12086
(-14.2857) 3.12086 3.12086 3.12086 3.12086 3.12086 3.12086 3.12086 3.12086
(14.2857) 3.12086 3.12086 3.12086 3.12086 3.12086 3.12086 3.12086 3.12086
(42.8571) 3.12086 3.12086 3.12086 3.12086 3.12086 3.12086 3.12086 3.12086
(71.4286) 3.12086 3.12086 3.12086 3.12086 3.12086 3.12086 3.12086 3.12086
(100.0) 3.12086 3.12086 3.12086 3.12086 3.12086 3.12086 3.12086 3.12086
[:, :, 5] ~ (:, :, 80):
(-100.0) (-71.4286) (-42.8571) (-14.2857) (14.2857) (42.8571) (71.4286) (100.0)
(-100.0) 5.32289 5.32289 5.32289 5.32289 5.32289 5.32289 5.32289 5.32289
(-71.4286) 5.32289 5.32289 5.32289 5.32289 5.32289 5.32289 5.32289 5.32289
(-42.8571) 5.32289 5.32289 5.32289 5.32289 5.32289 5.32289 5.32289 5.32289
(-14.2857) 5.32289 5.32289 5.32289 5.32289 5.32289 5.32289 5.32289 5.32289
(14.2857) 5.32289 5.32289 5.32289 5.32289 5.32289 5.32289 5.32289 5.32289
(42.8571) 5.32289 5.32289 5.32289 5.32289 5.32289 5.32289 5.32289 5.32289
(71.4286) 5.32289 5.32289 5.32289 5.32289 5.32289 5.32289 5.32289 5.32289
(100.0) 5.32289 5.32289 5.32289 5.32289 5.32289 5.32289 5.32289 5.32289
[:, :, 6] ~ (:, :, 100):
(-100.0) (-71.4286) (-42.8571) (-14.2857) (14.2857) (42.8571) (71.4286) (100.0)
(-100.0) 9.30165 9.30165 9.30165 9.30165 9.30165 9.30165 9.30165 9.30165
(-71.4286) 9.30165 9.30165 9.30165 9.30165 9.30165 9.30165 9.30165 9.30165
(-42.8571) 9.30165 9.30165 9.30165 9.30165 9.30165 9.30165 9.30165 9.30165
(-14.2857) 9.30165 9.30165 9.30165 9.30165 9.30165 9.30165 9.30165 9.30165
(14.2857) 9.30165 9.30165 9.30165 9.30165 9.30165 9.30165 9.30165 9.30165
(42.8571) 9.30165 9.30165 9.30165 9.30165 9.30165 9.30165 9.30165 9.30165
(71.4286) 9.30165 9.30165 9.30165 9.30165 9.30165 9.30165 9.30165 9.30165
(100.0) 9.30165 9.30165 9.30165 9.30165 9.30165 9.30165 9.30165 9.30165
So I guess the midrange Lab L values produce low mean relative luminance against viridis colors.
Visualizing seems consistent with that, the middle L values have some hard-to-see points. Or maybe I’m just fooling myself – those top-right and bottom-left dots are pretty hard to make out. Maybe @cormullion can say how off-base I am.
let fig = Figure()
viridis = ColorSchemes.viridis.colors
vgrid = repeat(viridis, 1, length(viridis))'
map(enumerate(axiskeys(MYCOLORS, 3))) do (i, L )
ax = Axis(fig[1,i]; title="L=$L", xlabel="a", ylabel="b")
heatmap!(ax, 1.1axiskeys(MYCOLORS, 1), 1.1axiskeys(MYCOLORS, 2), vgrid)
foreach(axiskeys(MYCOLORS, 1)) do a
c = vec(MYCOLORS(a, :, L))
scatter!(ax, fill(a, length(axiskeys(MYCOLORS, 2))), axiskeys(MYCOLORS, 2), color=c)
end
end
fig
end
distinguishable_colors
makes some colors too:
distinguished_colors(n, cs; kw...) = distinguishable_colors(length(cs)+n, cs; kw...)[length(cs)+1:end]
let fig = Figure()
viridis = ColorSchemes.viridis.colors
vgrid = repeat(viridis, 1, length(viridis))'
ax = Axis(fig[1,1,])
heatmap!(ax, vgrid)
n = 10
cs = distinguished_colors(n, viridis)
foreach(1:n) do k
scatter!(ax, fill(length(viridis)÷n*k, length(n)), range(10, .95length(viridis); length=n), color=circshift(cs, k))
end
fig
end
On the heatmap some L=100
colors
let n = 500, k = 25
fig, ax, plt = heatmap(rand(n,n))
colors = map(rand(-100:100, k), rand(-100:100, k)) do a,b
Lab(100, a,b)
end
vlines!(ax, range(0,n; length=k); color=colors)
fig
end
and the distinguishable_colors
let n = 500, k = 20
fig, ax, plt = heatmap(rand(n,n))
vlines!(ax, range(0,n; length=k); color=distinguished_colors(k, ColorSchemes.viridis.colors))
fig
end