# How to update Makie plot upon zooming?

**URL:** <https://discourse.julialang.org/t/how-to-update-makie-plot-upon-zooming/106788>\
**Category:** Visualization\
**Tags:** plotting, makie\
**Created:** [November 27, 2023, 7:14am UTC](https://discourse.julialang.org/t/how-to-update-makie-plot-upon-zooming/106788 "2023-11-27T07:14:57Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![Zetison](https://avatars.discourse-cdn.com/v4/letter/z/76d3ee/32.png) [@Zetison](https://discourse.julialang.org/u/Zetison)\
**Post date:** [November 27, 2023, 7:14am UTC](https://discourse.julialang.org/t/how-to-update-makie-plot-upon-zooming/106788/1 "2023-11-27T07:14:57Z")

</div>

I’m trying to update the plot with higher resolution when zooming in a Makie plot. But it seems events(ax).scroll is not triggered. Is this a bug? The following MWE illustrates this issue:

```julia
using GLMakie
 
function update_zoom!(ax,xlim)
    noPoints = 1000
    x = range(xlim[1]/noPoints,xlim[2],noPoints)
    y = sin.(1 ./ x)
 
    lines!(ax, x, y)
end
 
fig = Figure()
ax = Makie.Axis(fig[1, 1])
 
on(events(ax).scroll) do event
    println("Scroll event detected")
    xlims = ax.limits.x
    update_zoom!(event, ax)
end
 
update_zoom!(ax,[0.01,1])
fig

```

---

<div class="post-metadata">

**Author:** ![jules](https://avatars.discourse-cdn.com/v4/letter/j/41988e/32.png) [@jules](https://discourse.julialang.org/u/jules)\
**Post date:** [November 27, 2023, 7:33am UTC](https://discourse.julialang.org/t/how-to-update-makie-plot-upon-zooming/106788/2 "2023-11-27T07:33:15Z")

</div>

Try setting `priority = some_positive_integer` in the `on` call so your function gets called before the axis scroll interaction which consumes the event.

But you shouldn’t create new `lines!` on scroll, that will fill your axis up real quick. Look in the docs how animations using observables are done

---

<div class="post-metadata">

**Author:** ![Zetison](https://avatars.discourse-cdn.com/v4/letter/z/76d3ee/32.png) [@Zetison](https://discourse.julialang.org/u/Zetison)\
**Post date:** [November 27, 2023, 3:21pm UTC](https://discourse.julialang.org/t/how-to-update-makie-plot-upon-zooming/106788/3 "2023-11-27T15:21:40Z")

</div>

Thanks a lot for your quick reply. It worked nicely! I expanded upon the code and fixed some bugs for future users:

```julia
include("startup.jl")

using GLMakie
noPoints = 1000
function update_zoom!(l,xlims)
    x = range(xlims[1],xlims[2],noPoints)
    y = sin.(1 ./ x)
    l[1] = x
    l[2] = y
end
 
fig = Figure()
ax = Makie.Axis(fig[1, 1])

x = range(0.01,1,noPoints)
y = sin.(1 ./ x)

l = lines!(ax, x, y)

# Function to extract pixel to data coordinates
function extractMouseCoordinates(ax)
    mouse_pos = events(ax).mouseposition[]
    plot_origin = pixelarea(ax.scene)[].origin
    plot_widths = pixelarea(ax.scene)[].widths
    rectangle = ax.finallimits[]
    xlims = (rectangle.origin[1], rectangle.origin[1] + rectangle.widths[1])
    ylims = (rectangle.origin[2], rectangle.origin[2] + rectangle.widths[2])
    xrange = xlims[2] - xlims[1]
    yrange = ylims[2] - ylims[1]
    x = xlims[1] + (mouse_pos[1] - plot_origin[1]) * xrange / plot_widths[1]
    y = ylims[1] + (mouse_pos[2] - plot_origin[2]) * yrange / plot_widths[2]
    return (x, y, xlims, ylims, xrange, yrange)
end
 
on(events(ax).scroll, priority = 1) do event
    mouse_pos_x, mouse_pos_y, xlims, ylims, xrange, yrange = extractMouseCoordinates(ax)

    # Determine zoom factor (adjust the value for different zoom speed)
    zoom_factor = event[2]
    zoom_factor = zoom_factor > 0 ? 1/(zoom_factor+1) : -zoom_factor+1

    # Calculate the ratios of mouse position within current limits
    x_ratio = (mouse_pos_x - xlims[1]) / xrange
    y_ratio = (mouse_pos_y - ylims[1]) / yrange

    # Adjusted xrange and yrange
    adjusted_xrange = xrange * zoom_factor
    adjusted_yrange = yrange * zoom_factor

    # Calculate new limits based on mouse position ratio
    new_xlims = (
        mouse_pos_x - adjusted_xrange * x_ratio, 
        mouse_pos_x + adjusted_xrange * (1 - x_ratio)
    )
    new_ylims = (
        mouse_pos_y - adjusted_yrange * y_ratio, 
        mouse_pos_y + adjusted_yrange * (1 - y_ratio)
    )

    # Update limits
    ax.limits = (new_xlims..., new_ylims...)

    update_zoom!(l,new_xlims)
end

is_dragging = Ref(false)
start_pos = Ref((0.0,0.0))

# Event handlers
on(events(ax.scene).mousebutton, priority = 2) do event
    if event.button == Mouse.left
        if event.action == Mouse.press
            mouseInfo = extractMouseCoordinates(ax)
            start_pos[] = mouseInfo[1:2]
            is_dragging[] = true
        elseif event.action == Mouse.release && is_dragging[]
            mouseInfo = extractMouseCoordinates(ax)
            end_pos = mouseInfo[1:2]
            is_dragging[] = false

            # Set new limits based on the rectangle
            new_xlims = (min(start_pos[][1], end_pos[1]), max(start_pos[][1], end_pos[1]))
            new_ylims = (min(start_pos[][2], end_pos[2]), max(start_pos[][2], end_pos[2]))
            ax.limits = (new_xlims..., new_ylims...)

            update_zoom!(l,new_xlims)
        end
    end
end

fig

```
