How to use Log10 axis scale for Makie heatmaps

Hello,

I cannot figure out how to properly set a log10 axis scale for heatmaps. I get an error of invalid x-limits even if I set positive axis limits. I know log10 is not defined for negative values (when I dont want a complex number). As a workaround I can manually specify the ticklabels, but this is quite some work. The same code works for a scatterplot. Many thanks for your help!

using GLMakie

## Heatmap with log10 scales axes does not work
## even when I set axis limits
let
    xs = [ 10^2,  10^2,  10^3,  10^3]
    ys = [10^-3, 10^-2, 10^-3, 10^-2]
    zs = [1, 2, 3, 4]
    fig = Figure()
    ax1 = Axis(fig[1,1]; yscale=log10, xscale=log10) 
    limits!(ax1, 10^1, 10^3, 10^-3, 10^-1)
    heatmap!(ax1, xs, ys, zs)
    fig
end
# LoadError: Found invalid x-limits (-350.0f0, 1450.0f0) for scale log10 which is defined on the interval 0.0..Inf (open)

## it works for a scatterplot
let
    xs = [ 10^2,  10^2,  10^3,  10^3]
    ys = [10^-3, 10^-2, 10^-3, 10^-2]
    zs = [1, 2, 3, 4]
    fig = Figure()
    ax1 = Axis(fig[1,1]; yscale=log10, xscale=log10) 
    scatter!(xs, ys; color=zs, markersize=50)
    fig
end

## workaround: set manual ticklabels
let
    xs = [1, 1, 2, 2]
    ys = [1, 2, 1, 2]
    zs = [1, 2, 3, 4]
    fig = Figure()
    ax1 = Axis(fig[1,1]; 
        xticks=(1:2, ["10²", "10³"]),
        yticks=(1:2, ["10⁻³", "10⁻²"])) 
    heatmap!(xs, ys, zs)
    fig
end
1 Like

Confirmed with GLMakie v0.5.2, Makie v0.16.3.
Makie already has an open issue for non-linear grids which is not exactly about log scale, but might be related.
The link contains some code that might help to workaround this.

Since you already have a manual workaround, but generating tick labels by hand is cumbersome,
you might be interested in

custom_formatter(values) = map(
		v -> "10" * Makie.UnicodeFun.to_superscript(round(Int64, v)),
		values
	)

used in https://github.com/JuliaPlots/Makie.jl/issues/1405 for log scale colorbar
(see inside the first “Code for the above figure” revealer).

1 Like

Thanks for you reply! I was not aware of the automatic way to make superscript unicode numbers. I tried it before with the latextring function from the LaTeXStrings package. This was working, but then the font also changes.

edit: here was my ugly code

values = [0.001, 0.01]
latexstring.(repeat(["10^{"], length(values)) .* string.(Int.(log10.(values))) .* "}" )