Hover-over behaviour of mplcursors

Hi

I’m experimenting with mplcursors for the first time. I’d like to have an annotation appear when hovering over areas of a bar graph and disappear again when I leave that area.

Currently, I can only get the annotation to appear when over the bar but not disappear when no longer over it (without manual action or hover over another bar). I’d like it to automatically disappear.

I’m currently using this code as my basis to experiment with:
https://mplcursors.readthedocs.io/en/stable/examples/bar.html

Can anyone point me in the right direction?

Thanks
Laurence

This is not possible right now with mplcursors, although it should not be too hard to fix that. I’ll work on a patch… probably the API will be like hover={HoverMode.NoHover, HoverMode.Persistent, HoverMode.Transient} where the first two alias to False and True respectively. How does that sound?

1 Like

Sounds perfect to me. Thanks.

If nothing else, it’s allowed me to stop trying to find an answer for now. I have other fish I need to fry in the short term in any case. If this is on Github, would you like me to raise it as an issue for posterity?

Laurence

···

On Sun, 19 Jan 2020 at 18:51, anntzer.lee via Matplotlib nobody@discourse.matplotlib.org wrote:


anntzer.lee

    January 19

This is not possible right now with mplcursors, although it should not be too hard to fix that. I’ll work on a patch… probably the API will be like hover={HoverMode.NoHover, HoverMode.Persistent, HoverMode.Transient} where the first two alias to False and True respectively. How does that sound?


Visit Topic or reply to this email to respond.

To unsubscribe from these emails, click here.

It’s on https://github.com/anntzer/mplcursors and should work on master now; please give it a try (it still needs proper docs and some tests…).

Perfect. Thanks @anntzer.lee

Using the mplcursors bar chart example and testing all of the following scenarios

cursor = mplcursors.cursor(hover=mplcursors.HoverMode.Transient)
cursor = mplcursors.cursor(hover=2)

cursor = mplcursors.cursor(hover=mplcursors.HoverMode.Persistent)
cursor = mplcursors.cursor(hover=True)
cursor = mplcursors.cursor(hover=1

cursor = mplcursors.cursor(hover=mplcursors.HoverMode.NoHover)
cursor = mplcursors.cursor(hover=False)
cursor = mplcursors.cursor(hover=0)

I can confirm all of the following for you:

  1. new Transient hover functionality works as intended (thanks!)
  2. True & False values work exactly as before
  3. Transient = 2
  4. Persistent = 1 = True
  5. NoHover = 0 = False

You are welcome, thanks for the feature suggestion :slight_smile:

2 Likes

Happy to suggest.

I was just looking at your test script thinking that the least I could do to show my thanks is perhaps extend the tests for you but I see you got there before me. :+1:

Well, instead you can let me know what you are using mplcursors for :slight_smile: Always happy to hear about use cases.

Two possibilities for RepoDash

  1. annotate contributor stats for monthly opened/closed tickets in RepoDash
  2. annotate distribution of age at point of closure for monthly closed tickets (possibly complex/impossible*)

*Can you envisage using annotations to contain additional mini pop-up matplotlib visualisations?

Thanks for letting me know. I see that RepoDash doesn’t appear to use mplcursors yet (I assume you’re working on adding it); can you please let me know when it does? I’m trying to start compiling a user list in the docs.

As for 2, this would be tricky, I guess? In any case (if I understand correctly what you’re asking) this is more a feature request for matplotlib (drawing sub-figures within annotations?); mplcursors just calls annotate() and lets matplotlib draw the annotation.

  1. Yup. It’s a work in progress. Will do.
  2. Ah, I see. Good to know.

Hi @anntzer.lee

Here’s tweet with a gif showing my first use case for mplcursors.

I’m having trouble keeping the boxes highlighted while I’m hovering over them. Unless I remove my finger from the mousepad or (with a mouse attached) stop moving the mouse the moment the mouse pointer touches the bar the highlight only lasts momentarily.

Minimal working code example below (using border highlight only) that exhibits this behaviour for me. Can you replicate this behaviour yourself? Any thoughts on this?

Cheers
Laurence

import matplotlib.pyplot as plt
import mplcursors

fig, ax = plt.subplots()
ax.bar(range(9), range(1, 10), align="center")

cursor = mplcursors.cursor(hover=True)

@cursor.connect("add")
def on_add(sel):
    x, y, width, height = sel.artist[sel.target.index].get_bbox().bounds
    sel.annotation.set(text=f"{x+width/2}: {height}", position=(0, 5))
    sel.annotation.xy = (x + width / 2, y + height)
    sel.artist[sel.target.index].set_edgecolor('r')

@cursor.connect("remove")
def on_remove(sel):
    sel.artist[sel.target.index].set_edgecolor('w')

plt.show()

Thanks for the report, I can repro and agree with the bug.
Almost certainly this is because the highlighting code shares basically all event handling with the annotation code, but they should likely be slightly split so that the highlight doesn’t get removed until the cursor goes away. Probably not too difficult, again just needs to be done after tracking down the relevant code path. Do you want to give it a try? Otherwise feel free to open an issue on the bug tracker; I’ll put it on my todo list but can’t promise a date.

@anntzer.lee

Thanks for confirming that you can replicate. Useful to know that it’s not just me, my hardware or even my understanding of how mplcursors works (all equally likely possibilities).

If I get the time I might be tempted to look at it and see if I can figure out how to fix it. For now, I’ve just created an issue.