MakieOrg / Makie.jl

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

heatmap and contourf do not behave as expected or consistently with each other #2403

Open alex-robinson opened 1 year ago

alex-robinson commented 1 year ago

When using heatmap together with Colorbar, the resulting colorbar does not accurately reflect the bounds of the data. In some cases, extending triangles are shown for data values outside of colorrange when they shouldn't be, and vice versa. This behavior is also not consistent with contourf. This makes it difficult to use despite being a central plotting component for many analyses.

As a user, it would be very valuable to see the following improvements:

  1. Make heatmap and contourf work consistently with each other, with the same arguments when possible.
  2. When a Colorbar is plotted, make the appearance of extending triangles on either side automatically determined by default, based on whether the data itself extends beyond the selected colorbar range or not.
  3. Include optional arguments that allow the user to suppress the triangles, include them or change their colors by hand.

Note: this is somewhat related to Issue #1737.

To illustrate this issue, the following tests can be used:


# Define a matrix of random numbers ranging from 0 to 1.
z = rand(Float64, (10, 10));

# Plot values ranging from 0.2 to 0.8.
# Triangles expected on both sides, no triangles appear.
f, ax, hm = heatmap(z,colorrange=(0.2,0.8));
cb = Colorbar(f[:,end+1],hm,ticks=(0.0:0.2:1.0,string.(0.0:0.2:1.0)));
f

# Plot values ranging from 0.2 to 1.0, and include a colormap.
# Triangles expected on bottom, triangles appear on both sides.
f, ax, hm = heatmap(z,colorrange=(0.2,1.0),colormap=cgrad(:Paired_5));
cb = Colorbar(f[:,end+1],hm,ticks=(0.0:0.2:1.0,string.(0.0:0.2:1.0)));
f

# Plot ranging from 0.2 to 1.0 using contourf, and include a colormap.
# Triangles expected on bottom, no triangles appear.
f, ax, hm = contourf(z,levels=0.2:0.2:1.0,colormap=cgrad(:Paired_5));
cb = Colorbar(f[:,end+1],hm,ticks=(0.0:0.2:1.0,string.(0.0:0.2:1.0)));
f
``
Moelf commented 1 year ago

if you want to see the "highclip" triangle, you need to tell it what color you want to clip to:

julia> f, ax, hm = heatmap(z,colorrange=(0.2,0.8), highclip = :red, lowclip = :blue);
julia> cb = Colorbar(f[:,end+1],hm,ticks=(0.0:0.2:1.0,string.(0.0:0.2:1.0)));

image

alex-robinson commented 1 year ago

Yes, I have seen that this is possible, and this is a good tip to work around this issue. But it is not ideal, for example, when I want the triangles to assume the same first and last colors as determined by the colormap argument. Is there a way to tell heatmap to use those colors without explicitly figuring out what they are myself? I would hope that the function itself could do that work for me.

ffreyer commented 3 weeks ago

None of the original examples show triangles anymore