# Makie mouse event

**URL:** <https://discourse.julialang.org/t/makie-mouse-event/74786>\
**Category:** General Usage\
**Tags:** makie\
**Created:** [January 18, 2022, 8:29am UTC](https://discourse.julialang.org/t/makie-mouse-event/74786 "2022-01-18T08:29:02Z")\
**Posts on this page:** 11\
**Page:** 1

<div class="post-metadata">

**Author:** ![sransome](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/sransome/32/29810_2.png) [@sransome](https://discourse.julialang.org/u/sransome)\
**Post date:** [January 18, 2022, 8:29am UTC](https://discourse.julialang.org/t/makie-mouse-event/74786/1 "2022-01-18T08:29:02Z")

</div>

Hi,

I’m using the following to respond to mouse clicks for a chart with multiple Axis, ax1, ax2,ax3.

```julia
    on(events(ax1.scene).mousebutton, priority = 0) do event
        if event.button == Mouse.left
            println("mouse pressed")
            #println("hovered scene ",hovered_scene())
        end
        return Consume(false)
    end

```

The event fires reliably but it fires regardless which Axis the mouse is hovering over. Using hovered\_scene() appears to be the obvious solution to determine which axis but this gives me an error “hoevered\_scene is not implemented yet”

I also tried using `ispressed(ax1.scene,Mouse.left)` but this returns true when the button is pressed over any axis.

Am I doing something dumb here or is there another way I can determine the axis selected from within the mouse event callback?

thanks  
Steve

---

<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:** [January 18, 2022, 10:45am UTC](https://discourse.julialang.org/t/makie-mouse-event/74786/2 "2022-01-18T10:45:19Z")

</div>

There are currently a couple different ways to deal with makie’s event system, we haven’t figured out one perfect approach yet. For Axis I wrote some convenience methods that allow to attach/detach event handlers and the mouse events are already preprocessed into clicks, drags, etc., which is complicated to do manually.

It’s explained here in the docs [https://makie.juliaplots.org/stable/examples/layoutables/axis/#function\_interaction](https://makie.juliaplots.org/stable/examples/layoutables/axis/#function_interaction)

---

<div class="post-metadata">

**Author:** ![ffreyer](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ffreyer/32/21569_2.png) [@ffreyer](https://discourse.julialang.org/u/ffreyer)\
**Post date:** [January 18, 2022, 11:34am UTC](https://discourse.julialang.org/t/makie-mouse-event/74786/3 "2022-01-18T11:34:30Z")

</div>

The function you were looking for is `is_mouseinside(ax.scene)` . It checks whether the mouse is inside the boundary of the scene. Depending on how exact you want to be with your clicks you may also want to use `plt, idx = pick(scene, events(ax).mouseposition[])` to check which plot you’re hovering.

---

<div class="post-metadata">

**Author:** ![sransome](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/sransome/32/29810_2.png) [@sransome](https://discourse.julialang.org/u/sransome)\
**Post date:** [January 19, 2022, 5:12am UTC](https://discourse.julialang.org/t/makie-mouse-event/74786/5 "2022-01-19T05:12:29Z")

</div>

Thanks Frederic, that’s perfect. I had to use `Makie.is_mouseinside(ax,scene). ` Do you know why I had to use the Makie.?

Thanks  
Steve

---

<div class="post-metadata">

**Author:** ![sransome](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/sransome/32/29810_2.png) [@sransome](https://discourse.julialang.org/u/sransome)\
**Post date:** [January 19, 2022, 8:18am UTC](https://discourse.julialang.org/t/makie-mouse-event/74786/6 "2022-01-19T08:18:42Z")

</div>

I would like to use the the pick function as you suggested in order to delete elements I have previously added to the Axis, like a hline or vline.

I can use the `delete!(ax.scene,ax.scene.plots[someindex])` and that deletes the line but I can’t relate work out how to use the plt,idx returned by pick() to supply the parameters for delete!().

I think this is because I don’t understand the plots structure very well but I can’t find a beginners guide to how this works. Do you have any hints?

Thanks  
Steve

---

<div class="post-metadata">

**Author:** ![sransome](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/sransome/32/29810_2.png) [@sransome](https://discourse.julialang.org/u/sransome)\
**Post date:** [January 19, 2022, 8:34am UTC](https://discourse.julialang.org/t/makie-mouse-event/74786/7 "2022-01-19T08:34:44Z")

</div>

Thanks Jules, that looks like what I need to combine mouse clicks with keyboard buttons to annotate my charts. Will these helper methods work when I have multiple Axis?  
Thanks  
Steve

---

<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:** [January 19, 2022, 10:17am UTC](https://discourse.julialang.org/t/makie-mouse-event/74786/8 "2022-01-19T10:17:36Z")

</div>

Yes you can write the function once and then attach it to multiple axes one after the other. You don’t have to do it with an anonymous function and the do syntax, you can just pass a named function as the first argument.

---

<div class="post-metadata">

**Author:** ![ffreyer](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ffreyer/32/21569_2.png) [@ffreyer](https://discourse.julialang.org/u/ffreyer)\
**Post date:** [January 19, 2022, 12:07pm UTC](https://discourse.julialang.org/t/makie-mouse-event/74786/9 "2022-01-19T12:07:39Z")

</div>

> [@sransome](#):
>
> I think this is because I don’t understand the plots structure very well but I can’t find a beginners guide to how this works. Do you have any hints?

Plots have a tree structure which eventually ends with a few primitive plots types. `pick` can only see those. You can move up to the root plot with something like

```julia
plt, idx = pick(ax.scene, events(ax).mouseposition[])
while plt.parent isa AbstractPlot
    plt = plt.parent
end

```

---

<div class="post-metadata">

**Author:** ![sransome](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/sransome/32/29810_2.png) [@sransome](https://discourse.julialang.org/u/sransome)\
**Post date:** [January 20, 2022, 12:11pm UTC](https://discourse.julialang.org/t/makie-mouse-event/74786/10 "2022-01-20T12:11:43Z")

</div>

When I click on a vline, plt returned by pick is a LineSegment and I can’t see what idx represents. plt.parent is a scene so there seems no point moving up the tree but when I try to delete the plt returned by pick using  
`delete!(ax.scene,plt)` I get  
`ERROR: LineSegments{Tuple{Vector{Point{2, Float32}}}} not in scene!`

In the end I just want to annotate my charts by drawing hlines and vlines and then selected them with pick if I want to delete them.

If I look at the ax.scene.plots vector I can see the LineSegments are added to this vector and I can delete them using these indexes but I can’t see how to usie plt and idx returned by pick to find the correct index of the plots vector to delete.

I hate to keep asking ignorant questions but I can’t find any documentation so I’m not sure how to learn this stuff. What’s the best approach to get productive with these structures?

Thanks  
Steve

---

<div class="post-metadata">

**Author:** ![ffreyer](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ffreyer/32/21569_2.png) [@ffreyer](https://discourse.julialang.org/u/ffreyer)\
**Post date:** [January 20, 2022, 12:50pm UTC](https://discourse.julialang.org/t/makie-mouse-event/74786/11 "2022-01-20T12:50:42Z")

</div>

`idx` differs between plot types but it generally refers to the arguments you pass to the plot. I.e. for a scatter plot it’s the position of the hovered marker, for lines and linesegmets the last or next position.

Deleting `vlines!` works fine for me like you described. Maybe you’re clicking on different lines (i.e. the ones from axis)?

```julia
fig = Figure()
ax = Axis(fig[1, 1])
vlines!(ax, 0.5, linewidth=10)

on(events(ax.scene).mousebutton) do e
    plt, idx = pick(ax.scene, events(ax.scene).mouseposition[])
    @info typeof(plt)
    if plt !== nothing
        if plt.parent == ax.scene
            @info "in axis"
            delete!(ax.scene, plt)
        else
            @info "not in axis"
        end
    end
    false
end
fig

```

---

<div class="post-metadata">

**Author:** ![sransome](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/sransome/32/29810_2.png) [@sransome](https://discourse.julialang.org/u/sransome)\
**Post date:** [January 21, 2022, 1:49am UTC](https://discourse.julialang.org/t/makie-mouse-event/74786/12 "2022-01-21T01:49:27Z")

</div>

I really appreciate the help provided to beginners who are not software developers. As an engineer, the Julia ecosystem is a life changing tool but the learning curve is very steep for many of us. Thanks for taking the time to support us on the Julia journey.

Interestingly, when I changed  
`plt, idx = pick(ax.scene, mouseposition(ax.scene))`  
to what you suggested…  
`plt, idx = pick(ax.scene, events(ax.scene).mouseposition[])`  
the pick process seemed to work much more reliably. How I’m able to add and remove annotation lines at will and should be able to save the annotations once I better understand the ax.scene.plots structure.

Regards  
Steve
