Makie: plotting text at arbitrary position in `GridLayout`?

I asked how to plot some text at an arbitrary position in a Figure in
this thread . The simplest answer was to plot the text using the coordinates of fig.scene.

Then, my question here is, does a GridLayout has its own coordinate system?

Below is a sample image and the program that generates it. I want to add a piece of text to annotate the colorbar, but I don’t want to use fig.scene because the function that plots the contourf + colorbar is used as stand-alone or in a different layout.

Colorbar(... label = "...") is an option, except that the positioning of the label is (or seems to be) quite limited. I’d like to utilize the space right above the topmost numeric label of the colorbar.

using CairoMakie

"""
Contourf and colorbar.
[row,col] is for colorbar.
"""
function plot_xymap!(ax, gridlo, row, col, xs, ys, arr; asp)
  ax.xlabel="x"; ax.ylabel="y"
  co = contourf!(ax, xs, ys, arr)
  Colorbar(gridlo[row,col], co)
  rowsize!(gridlo, row, Aspect(1,1/asp))
#  text!(gridlo.scene, # <- Doesn't exist.
#        Point3f(0.9, 0.78, 3),
#        text="[units]", space=:relative)
end

function plot_xsect!(ax, xs, vec)
  ax.xlabel="x"; ax.ylabel="y"
  lines!(ax, xs, vec)
end


function plot_ysect!(ax, ys, vec)
  ax.ylabel="y"; ax.yaxisposition = :right
  lines!(ax, vec, ys)
end

xwid = 200
ywid = 100

func(x,y) = cos(2π*x/xwid) * sin(2π*y/ywid)

xs = 0:10:xwid
ys = 0:10:ywid

arr2d = func.(xs, reshape(ys,1,:))
xsect = arr2d[:,5]
ysect = arr2d[5,:]

fig = Figure()
ga = fig[1,1] = GridLayout()

axtop   = Axis(ga[1,1])
axmain  = Axis(ga[2,1])
axright = Axis(ga[2,3]) # skip Col 2 for the colorbar.

asp = xwid/ywid
graph_height = 0.6 # relative to the y-axis length
rowsize!(ga, 1, Aspect(1, graph_height/asp))
axright.aspect = graph_height
colsize!(ga, 3, Relative(0.25))
rowgap!(ga, 10)

linkxaxes!(axmain, axtop)
linkyaxes!(axmain, axright)
plot_xsect!(axtop,   xs, xsect)
plot_ysect!(axright, ys, ysect)
plot_xymap!(axmain, ga, 2, 2, xs, ys, arr2d, asp = asp)

Box(ga[2,3], color = (:red, 0.2), strokewidth = 0)

save("tmp.png", fig)

You can place a Label in the right protrusion space of the same cell the Colorbar is in:

using CairoMakie

"""
Contourf and colorbar.
[row,col] is for colorbar.
"""
function plot_xymap!(ax, gridlo, row, col, xs, ys, arr; asp)
  ax.xlabel="x"; ax.ylabel="y"
  co = contourf!(ax, xs, ys, arr)
  Colorbar(gridlo[row,col], co)
  Label(gridlo[row,col,Right()], valign = :top, "LABEL", padding = (5, 0, 0, 0))
  rowsize!(gridlo, row, Aspect(1,1/asp))
#  text!(gridlo.scene, # <- Doesn't exist.
#        Point3f(0.9, 0.78, 3),
#        text="[units]", space=:relative)
end

function plot_xsect!(ax, xs, vec)
  ax.xlabel="x"; ax.ylabel="y"
  lines!(ax, xs, vec)
end


function plot_ysect!(ax, ys, vec)
  ax.ylabel="y"; ax.yaxisposition = :right
  lines!(ax, vec, ys)
end

xwid = 200
ywid = 100

func(x,y) = cos(2π*x/xwid) * sin(2π*y/ywid)

xs = 0:10:xwid
ys = 0:10:ywid

arr2d = func.(xs, reshape(ys,1,:))
xsect = arr2d[:,5]
ysect = arr2d[5,:]

fig = Figure()
ga = fig[1,1] = GridLayout()

axtop   = Axis(ga[1,1])
axmain  = Axis(ga[2,1])
axright = Axis(ga[2,3]) # skip Col 2 for the colorbar.

asp = xwid/ywid
graph_height = 0.6 # relative to the y-axis length
rowsize!(ga, 1, Aspect(1, graph_height/asp))
axright.aspect = graph_height
colsize!(ga, 3, Relative(0.25))
rowgap!(ga, 10)

linkxaxes!(axmain, axtop)
linkyaxes!(axmain, axright)
plot_xsect!(axtop,   xs, xsect)
plot_ysect!(axright, ys, ysect)
plot_xymap!(axmain, ga, 2, 2, xs, ys, arr2d, asp = asp)

Box(ga[2,3], color = (:red, 0.2), strokewidth = 0)

fig

1 Like

I see. So, I guess the main difference between text!() and Label() is that the former plots the text at an arbitrary point disregarding the various boxes whereas the latter plots within and relative to the box.

Label is a Block, which is the group of objects that can partake in the layout, so it can communicate how much space it needs and shift other things around accordingly. But it’s just a relatively thin wrapper around text in the end