Skip to content

Heatmap with log scale colorbar (cscale) ? #1405

@ederag

Description

@ederag

Reposted from discourse,
with updated CairoMakie, figures and link to documentation.

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

image

Code for the above figure
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[]
		extended_tickvalues = [
			tickvalues[1] - (tickvalues[2] - tickvalues[1]);
			tickvalues;
			tickvalues[end] + (tickvalues[end] - tickvalues[end-1]);
		]
    	for (lo, hi) in zip(
				@view(extended_tickvalues[1:end-1]),
				@view(extended_tickvalues[2:end])
			)
        	interval = hi-lo
        	steps = log10.(LinRange(10^lo, 10^hi, 11))
        	append!(vals, steps[2:end-1])
    	end
		return filter(x -> vmin < x < vmax, 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))
	clims = (1e1, 1e4)  # natural display
	fig = Figure()
	ax, hm = heatmap(fig[1, 1], x, y, log10.(data), colorrange=log10.(clims),
		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.6.2) the cscale argument is just ignored:
image

also tried zscale and read the documentation of course, in particular
https://makie.juliaplots.org/stable/examples/layoutables/axis/index.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 value) on an underlying linear axis,
and tweak ticks, minorticks and tick labels.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions