I have been struggling to find the syntax for drawing a line on a color bar using CairoMakie. I just want to be able to get the colorbar axis and do something like hlines!(cbar.axis. 5, color=“red”).
There’s no extra colorbar axis scene like Axis has, the color cells are drawn directly into colorbar.blockscene
at the right pixel coordinates. You could draw into that as well but there’s no convenience to give you the right coordinates
Do we think this is worth making a feature request? I would have no idea how to go about the solution you suggested if that space doesn’t know how to do the coordinate mapping. It is a major disadvantage relative to some of the packages people are migrating from (like matplotlib via PythonPlot.jl).
I was trying to achieve something similar the other day. To hack around it I attempted to place a separate axis with hidden spines and decorations on top of the color bar so that I could plot into it, but I could not figure out how to correctly place this axis so that it lined up perfectly with the colorbar. @jules
– is there a not-too-complicated way of doing this?
Edit: Actually, I think I figured it out. The following code
using GLMakie
X = rand(20,20)
fig = Figure()
ax = Axis(fig[1,1])
hm = heatmap!(ax, X)
cbar = Colorbar(fig[1,2], hm)
clims = cbar.limits[]
clay = Makie.get_layout!(fig[1,2])
cbbox = clay.layoutobservables.computedbbox
top_axis = Axis(fig, bbox = cbbox)
xlims!(top_axis, 0, 1)
ylims!(top_axis, clims...)
hidedecorations!(top_axis)
hidespines!(top_axis)
hlines!(top_axis, 0.5; color = :red, linewidth = 5)
fig
produces this output:
It does seem to rely on some internals though, so probably not future proof.
What I do is just put an axis into the same figure layout position as the colorbar, and assign the same limits as the colorrange has:
Colorbar(fig[1,2]; colorrange, ...)
Axis(fig[1,2], limits=(0..1, colorrange))
hidedecorations!()
scatter!(...) # draws on this new axis
No internals, and approved by @jules on slack recently
This will break if you enable high or lowclip though, as the axis will not adjust for the triangles. But the inner box of the colorbar is not exposed to the outside
Here’s one way that works also with highclip/lowclip, although it uses an internal detail, the input arguments of the second plot of the colorbar, which is an image that is given the rectangle that the helper axis should also be placed at.
using CairoMakie
f = Figure()
ax = Axis(f[1, 1])
hm = heatmap!(ax, rand(10, 10) .* 100 .+ 10, colorrange = (20, 100), highclip = :cyan, lowclip = :black,
colormap = :plasma, colorscale = log10)
cb = Colorbar(f[1, 2], hm, ticks = 20:10:100)
rect = lift(cb.blockscene.plots[2][1], cb.blockscene.plots[2][2]) do (xmin, xmax), (ymin, ymax)
BBox(xmin, xmax, ymin, ymax)
end
inside_ax = Axis(f, bbox = rect, limits = @lift((0, 1, $(cb.limits)...)), yscale = cb.scale)
hidedecorations!(inside_ax)
hidespines!(inside_ax)
hlines!(inside_ax, 20:10:100, color = :lime, linewidth = 3)
f