When working with Makie.jl, a popular plotting package in Julia, it is common to encounter situations where you want to fix the y-axis limits (ylims) while allowing zooming to affect only the x-axis limits (xlims). In this article, we will explore three different ways to achieve this in Makie.jl.
Option 1: Using the `xlims!` and `ylims!` functions
The first option involves using the `xlims!` and `ylims!` functions provided by Makie.jl. These functions allow us to explicitly set the limits for the x and y axes, respectively. To fix the y-axis limits while allowing zooming to affect only the x-axis limits, we can set the y-axis limits to a fixed range and update the x-axis limits dynamically based on the zoom level.
using Makie
# Create a figure and axis
fig = Figure()
ax = Axis(fig)
# Generate some data
x = 1:100
y = sin.(x)
# Plot the data
lines!(ax, x, y)
# Set the initial x-axis limits
xlims!(ax, extrema(x))
# Set the fixed y-axis limits
ylims!(ax, (-1, 1))
# Function to update x-axis limits based on zoom level
function update_xlims!(ax, zoom_level)
xlims!(ax, extrema(x) .* zoom_level)
end
# Connect the update_xlims! function to the zoom event
connect!(ax, :zoom, update_xlims!)
# Show the figure
display(fig)
In this code snippet, we create a figure and axis using Makie.jl. We then generate some data and plot it using the `lines!` function. We set the initial x-axis limits using `xlims!` and the fixed y-axis limits using `ylims!`. We define a function `update_xlims!` that takes the axis and zoom level as arguments and updates the x-axis limits based on the zoom level. Finally, we connect the `update_xlims!` function to the zoom event using the `connect!` function.
Option 2: Using the `xlims` and `ylims` attributes
The second option involves directly manipulating the `xlims` and `ylims` attributes of the axis object. These attributes store the current limits for the x and y axes, respectively. To fix the y-axis limits while allowing zooming to affect only the x-axis limits, we can set the y-axis limits to a fixed range and update the x-axis limits dynamically based on the zoom level.
using Makie
# Create a figure and axis
fig = Figure()
ax = Axis(fig)
# Generate some data
x = 1:100
y = sin.(x)
# Plot the data
lines!(ax, x, y)
# Set the initial x-axis limits
ax.xlims = extrema(x)
# Set the fixed y-axis limits
ax.ylims = (-1, 1)
# Function to update x-axis limits based on zoom level
function update_xlims!(ax, zoom_level)
ax.xlims = extrema(x) .* zoom_level
end
# Connect the update_xlims! function to the zoom event
connect!(ax, :zoom, update_xlims!)
# Show the figure
display(fig)
In this code snippet, we create a figure and axis using Makie.jl. We then generate some data and plot it using the `lines!` function. We set the initial x-axis limits by directly assigning the `xlims` attribute of the axis object. Similarly, we set the fixed y-axis limits by assigning the `ylims` attribute. We define a function `update_xlims!` that takes the axis and zoom level as arguments and updates the x-axis limits based on the zoom level. Finally, we connect the `update_xlims!` function to the zoom event using the `connect!` function.
Option 3: Using the `xlims` and `ylims` attributes with reactive programming
The third option involves using reactive programming to automatically update the x-axis limits based on the zoom level. Reactive programming allows us to define dependencies between variables and automatically update them when their dependencies change. In this case, we can define a reactive variable for the x-axis limits and update it based on the zoom level.
using Makie
using Reactive
# Create a figure and axis
fig = Figure()
ax = Axis(fig)
# Generate some data
x = 1:100
y = sin.(x)
# Plot the data
lines!(ax, x, y)
# Set the fixed y-axis limits
ax.ylims = (-1, 1)
# Define a reactive variable for the x-axis limits
xlims = Signal(extrema(x))
# Function to update x-axis limits based on zoom level
function update_xlims!(ax, zoom_level)
xlims[] = extrema(x) .* zoom_level
end
# Connect the update_xlims! function to the zoom event
connect!(ax, :zoom, update_xlims!)
# Update the x-axis limits when the reactive variable changes
reactive_update!(ax, xlims) do ax, xlims
ax.xlims = xlims
end
# Show the figure
display(fig)
In this code snippet, we create a figure and axis using Makie.jl. We then generate some data and plot it using the `lines!` function. We set the fixed y-axis limits by assigning the `ylims` attribute of the axis object. We define a reactive variable `xlims` for the x-axis limits and set its initial value to the extrema of the x data. We define a function `update_xlims!` that takes the axis and zoom level as arguments and updates the reactive variable `xlims` based on the zoom level. We connect the `update_xlims!` function to the zoom event using the `connect!` function. Finally, we use the `reactive_update!` function to update the x-axis limits of the axis object when the reactive variable changes.
After exploring these three options, it is clear that the third option, using the `xlims` and `ylims` attributes with reactive programming, provides the most flexible and elegant solution. It allows for automatic updates of the x-axis limits based on the zoom level without the need for explicit function calls or assignments. This approach leverages the power of reactive programming to simplify the code and make it more maintainable.