Heatmap with log scale colorbar (cscale)

Makie is awesome, looks like everything is doable :slightly_smiling_face:,
for instance, this heatmap with log scale color axis (exactly what I wanted):

Code for the above figure
# in one Pluto.jl cell
using CairoMakie

# another Pluto.jl Cell
let
	# cf. https://github.com/JuliaPlots/Makie.jl/issues/822#issuecomment-769684652
	# with scale argument that is required now
	struct LogMinorTicks end
	
    function MakieLayout.get_minor_tickvalues(
			::LogMinorTicks, scale, tickvalues, vmin, vmax
	)
    	vals = Float64[]
    	for (lo, hi) in zip(
				@view(tickvalues[1:end-1]),
				@view(tickvalues[2:end])
			)
        	interval = hi-lo
        	steps = log10.(LinRange(10^lo, 10^hi, 11))
        	append!(vals, steps[2:end-1])
    	end
    	vals
	end
	
	custom_formatter(values) = map(
		v -> "10" * Makie.UnicodeFun.to_superscript(round(Int64, v)),
		values
	)
	
	x = 10.0.^(1:0.1:4)
	y = 1.0:0.1:5.0
	data = x .* ones(Float64, 1, length(y))
	fig = Figure()
	ax, hm = heatmap(fig[1, 1], x, y, log10.(data),
		axis=(;xscale=log10,
			   xminorticksvisible=true,
			   xminorticks=IntervalsBetween(9))
	         )
	cb = Colorbar(fig[1, 2], hm;
		tickformat=custom_formatter,
		minorticksvisible=true,
		minorticks=LogMinorTicks()
	)
	fig
end

But it was a bit involved for a newcomer. Here is how I would have expected it to work:

x = 10.0.^(1:0.1:4)
y = 1.0:0.1:5.0
data = x .* ones(Float64, 1, length(y))
fig = Figure()
ax, hm = heatmap(fig[1, 1], x, y, data,
	axis=(;xscale=log10, 
		   xminorticksvisible=true, xminorticks=IntervalsBetween(9),
		   cscale=log10)
         )
Colorbar(fig[1, 2], hm)

Currently (CairoMakie v0.5.9) the the cscale argument is just ignored:

I also tried zscale and read the documentation of course, in particular
http://makie.juliaplots.org/stable/makielayout/axis.html#Log-scales-and-other-axis-scales

Would it make sense to add this cscale argument, for symetry with xscale or yscale ?
It has exactly the same meaning:
Actually plot log10(axis values) on an underlying linear axis,
and instead of changing the label to log10(label),
tweak ticks, minorticks and tick labels.

2 Likes

you do the same in the Colorbar call, i.e.,
Colorbar(fig[1,2], pltHeat, scale = log10). Here, an example with log scales in all directions.
https://lazarusa.github.io/BeautifulMakie/heatmaps/heatmapLogIrregular/

unfortunately, I’m doing first a colormap with a logscale. cmap = cgrad(:CMRmap, scale = :log), but is just one line, and it works.

Thanks for the answer, BeautifulMakie will be useful.
But I already tried that. The issue is that the colormap would not be the regular one.
For instance, the blue area is smaller in the scaled colormap,
and larger in the heatmap.
With this test data, used especially to show that, the gradient should look like the colormap.

Code
let   # to test in a Pluto cell
	x = 10.0.^(1:0.1:4)
	y = 1.0:0.1:5.0
	data = x .* ones(Float64, 1, length(y))
	fig = Figure()
	cmap = cgrad(:viridis, scale=:log10)
	ax, hm = heatmap(fig[1, 1], x, y, data; colormap=cmap,
		axis=(;xscale=log10,
			   xminorticksvisible=true,
			   xminorticks=IntervalsBetween(9))
	         )
	cb = Colorbar(fig[1, 2], hm;
		minorticksvisible=true,
		minorticks=IntervalsBetween(9),
		scale=log10
	)
	fig
end

your are right. That’s definitely wrong. Probably you should file an issue in Makie.

1 Like

It seems that this issue persists in Makie v0.15.3. Have you filed an issue in the repo?

Thanks for the reminder. To allow for further discussion here, I intended to let one week pass, which became months :man_facepalming:.
Just filed, with up to date Makie, plots and links:

1 Like