Makie, how to move `xlabel` to the right?

For example:

the X [GeV]

1 Like

So this is a really ugly solution, but hey, it works.

using GLMakie

f = scatter(rand(100), rand(100))
f.axis.xlabel = "x"

# Originally it was [416.0, 33.36] and this below moved it to the left
f.axis.xaxis.elements[:labeltext].input_args[1][] = [306.0, 33.36]

I would assume there is a specialized function, but with Makie I find it easier to just roam around the objects until I find a plausible Observable. :wink:

just like many things, these numbers are absolute coordinates (data dependent) :frowning:

Are you sure they are not pixels? So you should know in advance where to put it (you could script is as a fraction of explicitly declared resolution).

even if they are pixels, how’d I know in advance, no matter, I mean it’s not a friendly solution at any rate.

Ok, fine. Let’s cook up a nicer one.

Try this:

function move_xlabel!(axis)
    ax_lend = axis.xaxis.elements[:axisline][1].val[1][1]
    ax_rend = axis.xaxis.elements[:axisline][1].val[2][1]

    label_pos = axis.xaxis.elements[:labeltext][1].val[1][1]

    translate!(axis.xaxis.elements[:labeltext], ax_rend-label_pos, 0, 0)
    axis.xaxis.elements[:labeltext].attributes[:align][] = (:right, :top)
end

And then just:

using GLMakie

fig, axis, plot = scatter(rand(100), rand(100))
axis.xlabel = "This is on the right!"
move_xlabel!(axis)

For me it aligns the right edge of the xlabel to the end of x-axis.
Also, making the function more generic should provide a tool to move both labels to any corner.
You can also add an offset parameter in the subtraction in translate! to move it a bit off axis, if needed.

2 Likes

Looks pretty cool! I whipped up a quick and dirty dynamic version, which should be able to translate the axis xlabel to any halign, even outside (0,1), and keep abreast of changing layouts.

function move_xlabel!(axis, halign = 1.0)
    0 <= halign <= 1 || @warn "Halign outside of (0, 1)!  Be warned."

    label_pos = @lift $(axis.xaxis.elements[:labeltext][1])[1][1] # get the label position in the x dimension

    lift(axis.scene.px_area, label_pos) do px_area, current_pos
        xwidth = px_area.widths[1] # the width of the scene
        desired_offset = xwidth * halign
        translate!(axis.xaxis.elements[:labeltext], desired_offset - current_pos, 0, 0)
    end
    # TODO: don't set this, let the user do it.
    axis.xaxis.elements[:labeltext].align[] = (:right, :top)
end

Executing this code,

f, a, p = lines(rand(10))
a.xlabel = "Hello there!"
move_xlabel!(a, 0.9)

I get this output:

which seems pretty good! One could theoretically implement something similar for the y-label as well.

You could also just throw a separate Label below. E.g. Label(f[2, 1], "Test ", halign = :right, tellwidth = false). (You can also set halign to a fraction like 0.8)

1 Like

Someone could make a PR to Makie which allows alignment to be set on the LineAxis label, :top and :bottom or number for y and :right, :left or number for x orientation. That should not be more difficult than coming up with hacks :slight_smile:

1 Like