MakieOrg / Makie.jl

Interactive data visualizations and plotting in Julia
https://docs.makie.org/stable
MIT License
2.4k stars 310 forks source link

log scaling of axes can break heatmaps #2615

Open FHoltorf opened 1 year ago

FHoltorf commented 1 year ago

Hey,

I wanted to do something like

fig = Figure()
ax = Axis(fig[1,1], xscale = log10)
heatmap!(ax, 10.0 .^ range(-9,0), randn(10), randn(10,10))

which errored due to

ERROR: Found invalid x-limits (-3.5f-9, 1.45f0) for scale log10 which is defined on the interval 0.0..Inf (open)

which is rather surprising.

Interestingly,

fig = Figure()
ax = Axis(fig[1,1], xscale = log10)
heatmap!(ax, 10.0 .^ range(-10,0), randn(10), randn(10,10))

works so I suspect it has to do with how the left most grid point is automatically generated.

Best, Flemming

EdsterG commented 1 year ago

It looks like you have some tiny numbers that, due to the way floats work, become a tiny negative number near zero when aggregated in the heatmap. Have you tried using pseudolog10 or Symlog10 instead? They work with negative values.

ffreyer commented 1 year ago

You can pass positions of the centers of each heatmap cell or for the edges of each heatmap cell.

In the first version you're specifying centers, which get converted to edges as 0.5 .* [xs[1] - xs[2]; xs[2:end] .- xs[1:end-1]; xs[end] - xs[end-1]] before conversions apply. That's how you get a negative number. In the second call you specify edges, avoiding that.

I guess we should ask here whether it makes more sense to calculate edges before or after transformations like log10. I.e. with xs = [1, 10, 100] should we have edges [-4.5, 5.5, 55, 155] or 10 .^ [0.5, 1.5, 2.5, 3.5]?

Sbozzolo commented 9 months ago

I am having a the same issue with the following non-uniform data:

[23.333333333333663, 165.65471240240066, 310.92987555627724, [...] 23706.2698752983, 29999.99927620745]

Error:

ERROR: Found invalid y-limits (-47.827354f0, 33146.863f0) for scale log10 which is defined on the interval 0.0 .. Inf (open)

Given that all my data is positive, it took me a while to track this to being a lower edge of a cell.

musoke commented 6 months ago

I am also having this issue.

Have you tried using pseudolog10 or Symlog10 instead? They work with negative values.

This does get a plot out but it is misleading and/or nonsense, in that it suggests data ranges that include 0 whereas the variable of interest is strictly positive if a log transform is applicable.

I guess we should ask here whether it makes more sense to calculate edges before or after transformations like log10. I.e. with xs = [1, 10, 100] should we have edges [-4.5, 5.5, 55, 155] or 10 .^ [0.5, 1.5, 2.5, 3.5]?

I think this is the direction towards a solution - the edges should be calculated after transformation. Not only would this change fix this bug, it would make other plots with heatmaps and log scales more intuitive too.

I can attempt this change if it is desired and someone points me in the right direction.