5

I am using a cursor widget in an interactive Matplotlib plot like so:

cursor = Cursor(ax1, useblit=True, color='red', linewidth=1)
cid = fig.canvas.mpl_connect('button_press_event', on_click)

Works well. The on_click function takes the x,y click locations and does some supplemental plotting. Basic stuff.

When I activate the zoom tool I am also capturing the click. Is it necessary to bind an activate and deactivate key stroke to the widget a la the RectangleSelector example or does a method exist that knows the state of the toolbar items?

Example of the selector on/off from the RectangleSelector example:

def toggle_selector(event):
    if event.key in ['Q','q'] and toggle_selector.RS.active:
        toggle_selector.RS.set_active(False)
    if event.key in ['A', 'a'] and not toggle_selector.RS.active:
        toggle_selector.RS.set_active(True)

3 Answers 3

9

That isn't public state, but you can check

fig.canvas.manager.toolbar._active is None

which will be True if the toolbar is not trying to grab clicks (either through pan or zoom).

You are reaching in and touching internal state which can change at any time, so use this at your own risk. The developers have no compunction about changing anything that starts with a _* with no deprecation period.

Sign up to request clarification or add additional context in comments.

5 Comments

Thanks. Checking if fig.canvas.manager.toolbar._active is not None: ignore_custom_cursor_clicks. Any chance that, as Matplotlib increases interactivity, public access will be made available?
There is actually a push to re write the tool bar going on now. You should create an issue I github asking for this. Include @tacaswell in the text so I get pinged
Any update on there being a public method for this, since the question in 2013?
There is a draft version of the new tool bar which shipped with 1.5, but it only supports gtk. There is a major re-writing of the GUI classel sitting in review that is blocking building out the new toolbar on the other backends. Getting the GUI changes reviewed is a priority for 2.1 (late summer / early fall 2016)
for matplotlib version 3.3 and above see this answer
4

The accepted answer doesn't work anymore for matplotlib version 3.3 due to this commit. When using the standard NavigationToolbar2 you could use its mode property instead.

Example similar to ImportanceOfBeingErnest's answer:

import matplotlib.pyplot as plt

fig, ax = plt.subplots()

def on_click(evt):
    state = fig.canvas.manager.toolbar.mode
    if state == '':
        print("no tool selected")
    else:
        print(f"{state} selected")

cid = fig.canvas.mpl_connect('button_press_event', on_click)

plt.show()

Comments

1

Since the toolmanager toolbar is available for more backends now, it might be useful here.

import matplotlib.pyplot as plt
plt.rcParams['toolbar'] = 'toolmanager'

fig, ax = plt.subplots()

def on_click(evt):
    state = fig.canvas.manager.toolbar.toolmanager.active_toggle["default"]
    if state is None:
        print("no tool selected")
    else:
        print(f"{state} selected")

cid = fig.canvas.mpl_connect('button_press_event', on_click)

plt.show()

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.