How to implement Value Suppressing Colormaps in Makie

I would like to implement Value Suppressing Colormap described in this paper https://dl.acm.org/doi/abs/10.1145/3173574.3174216


Which requires:

  1. triangular colorbar
  2. bivariate colormap, where I can manipulate color hue be changing saturation and lightness

At least how I understand it :slight_smile:
Any ideas? Is it even possible in Makie?

1 Like

Very interesting. Thanks for sharing the triangular map.

We implemented the bivariate map in our GeoStats.viewer with Makie.jl, and it would be awesome to replace it with the triangular one.

If you can work on a package that takes a vector of Distributions.jl objects and uses this triangular map to show location and spread statistics, that would be neat.

1 Like

To be more precise, we managed to abstract this concept in the Colorfy.jl package, which takes a vector of objects and returns a vector of colors for plotting. The exact code that handles Distributions.jl objects is stored in an extension:

1 Like

@juliohm great tool! Thank you!
But is it possible to send there a vector of different transparency values for each heatmap value to represent uncertainty variations?

You can pass a vector of alphas to the colorfy function and it is demonstrated in the README. If you can submit a PR to improve our Distributions.jl extension with the triangular map above, we can happily review and merge. That way users could simply colorfy(distributions) to get the final colors for plotting with Makie.jl

I shared this recipe some time ago, maybe this capability should be added to Makie.jl directly?..
Basically, image() but alpha can be an array of values:

@recipe ImageAlpha (
		x::Makie.EndPoints,
		y::Makie.EndPoints,
		image::AbstractMatrix{<:Number}) begin
	Makie.MakieCore.documented_attributes(Makie.Image)...
	alpha = nothing
	alpharange = 0..1
end

function Makie.plot!(p::ImageAlpha)
	alpha = p.alpha[]
	p.alpha = 1
	Makie.color_and_colormap!(p, p.image)
	imcolors = @lift Makie.to_color($(p.calculated_colors))
	alphas_interval = @lift @something(extrema($(p.alpharange)), extrema(alpha))
	alpha = @lift clamp.((alpha .- $alphas_interval[1]) ./ ($alphas_interval[2] - $alphas_interval[1]), 0, 1)
	imcolors_a = @lift Makie.coloralpha.($imcolors, $alpha)
	image!(p, Makie.shared_attributes(p, Image), imcolors_a)
	return p
end

Makie.convert_arguments(::Type{<:ImageAlpha}, args...) = Makie.convert_arguments(ImageLike(), args...)

Colorfy.jl is a lightweight dependency that handles missing values, unitful values, etc. through package extensions. We created it to facilitate the definition of colorful representations for any Julia type. The API is quite stable at this point. Makie.jl could leverage this API to display Julia objects as colors in various plots.

There are a lot of reasonable useful ways to turn a Julia object (even just a Normal distribution) to a color + alpha, meaning that there isn’t any “fundamentally correct” way to do that.
That’s why it would make sense to have a simpler straightforward API in a plotting package itself. Plotting “image with alpha” is well-defined, there’s just one way to do that.

Do we need these other useful ways in practice though? Or just “the most useful” way that is the result of research like the one linked by the OP?

Your request to add support in Makie.jl for “image + alpha” is an (important) orthogonal request. I believe the OP and I are seeking the most useful colorful representation for a vector of objects, which happens to be a vector of Distributions.jl (or uncertainties).