Determining xlims

Hi,

I really like the ability of Makie to set the x and y limits automatically but sometimes I want to use the limits to fine tune my plot. Is there a way of returning the x and y limits for an axis when they have been automatically set?

Thanks
Steve

1 Like

Hey Steve,

i’m not sure if there is a nicer option already but you can get them from the Axis internals:

using GLMakie
fig, ax, p = plot(rand(Point2, 4))

rectangle = ax.finallimits[]
xlimits = (rectangle.origin[1], rectangle.origin[1] + rectangle.widths[1])
ylimits = (rectangle.origin[2], rectangle.origin[2] + rectangle.widths[2])

Alternatively define a function to get them as Observables for the true interactive Makie experience

xlims(ax::Axis) = @lift ($(ax.finallimits).origin[1], $(ax.finallimits).origin[1] + $(ax.finallimits).widths[1])
ylims(ax::Axis) = @lift ($(ax.finallimits).origin[2], $(ax.finallimits).origin[2] + $(ax.finallimits).widths[2])

Shoutout to Plots.jl for

using Plots
plot(sin)
xlims()
# (-5.3, 5.3)
ylims()
# (-1.0596986628031682, 1.059331996217173)
1 Like
xlims(ax::Axis) = @lift ($(ax.finallimits).origin[1], $(ax.finallimits).origin[1] + $(ax.finallimits).widths[1])
ylims(ax::Axis) = @lift ($(ax.finallimits).origin[2], $(ax.finallimits).origin[2] + $(ax.finallimits).widths[2])

xlims() = xlims(current_axis())
ylims() = ylims(current_axis())

:stuck_out_tongue: (plot(sin) still not possible in Makie though)

Is this equivalent:

xlims(ax::Axis=current_axis()) =
    @lift ($(ax.finallimits).origin[1], $(ax.finallimits).origin[1] + $(ax.finallimits).widths[1])
ylims(ax::Axis=current_axis()) =
    @lift ($(ax.finallimits).origin[2], $(ax.finallimits).origin[2] + $(ax.finallimits).widths[2])
1 Like

Thanks hexader, that’s a great help.

Just to make sure I have this correct…

this line xlims(ax::Axis) = @lift ($(ax.finallimits).origin[1], $(ax.finallimits).origin[1] + $(ax.finallimits).widths[1])
creates an observable for the finallimits
this observable it is initialised using xlims() = xlims(current_axis())

so, I should then create another observable that listens for changes to xlims()?

Does this look something like

makeadjustment = lift(xlims()) do
      my code to alter the plot
end

Thanks
Steve

Nearly. lift would create a new Observable makeadjustment which follows the changes of xlims(). If you want to call a specific function on change use on:

using GLMakie
fig, ax, p = plot(rand(Point2, 4))

xlims(ax::Axis=current_axis()) = @lift ($(ax.finallimits).origin[1], $(ax.finallimits).origin[1] + $(ax.finallimits).widths[1])
ylims(ax::Axis=current_axis()) = @lift ($(ax.finallimits).origin[2], $(ax.finallimits).origin[2] + $(ax.finallimits).widths[2])

on(xlims()) do l
    println("xlmits changed to $l")
end

xlims!(-2, 2) # prints "xlimits changed to (-2, 2)"

This function will be only called on change though and not on definition. So maybe you want to call autolimits!(ax) again after the on block to trigger the reaction.

Thanks hexaeder, that’s crystal clear now.