Skip to content

Axes.format_cursor_data lacks documentation and seems unused #12279

Closed

Description

@jatentaki

Bug report

Bug summary
By default, the imshow plots format the bottom tooltip as x={x}, y={y} [{z}]. I wanted to change this behavior, so I followed this answer. However, it seems that with newer version of mpl, Axes.format_coord only controls the coordinate format and not the z value, which is shown in square parentheses. Looking at https://matplotlib.org/api/axes_api.html#interactive, I find it intuitive that Axes.format_cursor_data would do what I need, however it appears to do nothing (or, at the very least, I cannot get to trigger it with the code below).

Code for reproduction

import numpy as np
import matplotlib.pyplot as plt

img = np.sin(np.linspace(-4, 4, 50)).reshape(-1, 1) + np.zeros((1, 50))

fig, ax = plt.subplots()
ax.imshow(img)

def wrapper(f):
    def wrapped(*args, **kwargs):
        print(f.__name__, 'is called!')
        return f(*args, **kwargs)
    return wrapped

ax.format_cursor_data = wrapper(ax.format_cursor_data)
plt.show()
# now play around with the plot and try to make it print something

Actual outcome
No message is being printed when mousing over the figure.

Expected outcome
The print statement from wrapped firing when mousing over the figure.

Note
I may be misunderstanding the API by expecting Axes.format_cursor_data to format the value in square parentheses, when in reality it does something completely different. In this case, please consider this issue as a request for documentation instead. I encountered this problem while troubleshooting another apparent bug, which I will submit in a moment.
Edit: the other issue is #12282.

Matplotlib version

  • Operating system: Xubuntu 18.04
  • Matplotlib version: 2.1.2
  • Matplotlib backend (print(matplotlib.get_backend())): Qt5Agg
  • Python version: 3.6

Default conda channel.

Activity

  1. ImportanceOfBeingErnest commented on Sep 25, 2018

    @ImportanceOfBeingErnest
    Member

    You will need to use the image's format_cursor_data method. Not the one of the axes.

    import numpy as np
    import matplotlib.pyplot as plt
    
    img = np.sin(np.linspace(-4, 4, 50)).reshape(-1, 1) + np.zeros((1, 50))
    
    fig, ax = plt.subplots()
    im = ax.imshow(img)
    
    def wrapper(f):
        def wrapped(*args, **kwargs):
            print(f.__name__, 'is called!')
            return f(*args, **kwargs)
        return wrapped
    
    im.format_cursor_data = wrapper(im.format_cursor_data)
    plt.show()
    

    Note that format_cursor_data will just format the data, so in a simplified manner it will do

    def format_cursor_data(data):
        return "[" + str(data) + "]"
    

    Not sure if that is what you're looking for?

  2. ImportanceOfBeingErnest commented on Sep 26, 2018

    @ImportanceOfBeingErnest
    Member

    I labeled this with "Documentation" now, yet I'm not entirely sure what to document where. Maybe you can clarify a bit, @jatentaki.

  3. jatentaki commented on Oct 6, 2018

    @jatentaki
    Author

    @ImportanceOfBeingErnest sorry for not replying for so long. What you've just explained is sound, but it's difficult to find it by oneself in the documentation.

    First, I think the comments in the interactive section of Axes docs could use more explanation. "Return cursor data string formatted" is not very telling, unless the term cursor data is explained. In other words, I know there is some string being formatted, but I still have no clue in which circumstances this method is used, and where this string emerges. Is it what is being used when mousing over an ax in which nothing has been drawn?

    Secondly, AxesImage.get_cursor_data(event) is similiarly ambiguous - there is no hint when and where this data is being used. This method looks like some implementation detail and probably wouldn't catch my attention when trying to change the mouseover tooltip.

    Finally, there should be some discoverable (=googleable) resource explaining how these methods differ and when to use which. As my example shows, it's possible to read the docs trying to change the format of value tooltip and not manage to find this information. This issue itself may be enough, as this is probably not a common issue, and a full cookbook example is probably more work than it's worth, but some sweet spot in between would be ideal.

  4. ImportanceOfBeingErnest commented on Oct 6, 2018

    @ImportanceOfBeingErnest
    Member

    I think essentially this example is what is meant to be discoverable for users.

    I also think get_cursor_data is rarely called by any user. The Axes.get_cursor_data() method is not used at all as far as I can see. It's just there because Axes inherits from Artist and each Artist has this method. Therefore the docstring is so general, because Artist cannot know for which purpose any child may want to use it.
    For some artists overriding this method makes sense, as e.g. for the image. So we can write a bit more into the AxesImage.get_cursor_data docstring. Any suggestion? Maybe:

    Given an event, returns the image data for the event's location. This is e.g. used in the NavigationToolbar2's mouse_move function to obtain the data shown in the tooltip in many backends.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions