3

Matplotlib Widget Buttons event and fig.canvas.mpl_connect('button_press_event') will both be triggered when mouse is clicked against the button.

My problem are :

1) how to make fig.canvas.mpl_connect('button_press_event') event have a higher priority ? and 2) how to tell within an fig.canvas.mpl_connect('button_press_event') event whether the button is being clicked or not.

import matplotlib.pyplot as plt
from matplotlib.widgets import Slider, Button, RadioButtons


fig = plt.figure()
# plotting
X=[1,2,3]
Y=[10,20,30]
ax  = fig.add_subplot(1, 1, 1)
ax.plot(X,Y,'bo-')
ax.grid()
ax.legend()
X1=[]
Y1=[]

def on_press(event):
    print "canvas clicked"
    print "how can I tell whether the button is clicked?"
    print event
def on_button_clicked(event):
    print "button clicked"
    print event
axnext = plt.axes([0.81, 0.05, 0.1, 0.075])
bnext = Button(axnext, 'Next')
bnext.on_clicked(on_button_clicked)
fig.canvas.mpl_connect('button_press_event', on_press)
plt.show()

2 Answers 2

2

About the first point, why do you need that? Can you just ignore the event in that case?

Regarding the second point, you can use bnext.label.clipbox.get_points() to extract the coordinates of the button, and compare them with the coordinates of the mouse event, like in the example below:

import matplotlib.pylab as plt
from matplotlib.widgets import Button


fig,ax = plt.subplots()
ax.plot([1,2,3],[10,20,30],'bo-')
axnext = plt.axes([0.81, 0.05, 0.1, 0.075])
bnext = Button(axnext, 'Next')

(xm,ym),(xM,yM)=bnext.label.clipbox.get_points()

def on_press(event):

    if xm<event.x<xM and ym<event.y<yM:
        print "Button clicked, do nothing. This triggered event is useless."
    else:
        print "canvas clicked and Button not clicked. Do something with the canvas."
    print event
def on_button_clicked(event):
    print "button clicked, do something triggered by the button."
    print event

bnext.on_clicked(on_button_clicked)
fig.canvas.mpl_connect('button_press_event', on_press)
plt.show()
Sign up to request clarification or add additional context in comments.

Comments

0

You could also use the axes that event happened in as in the code below. Note, text is inserted into the plot rather than using prints just because I was developing this in Jupyter and interactive plots don't show print statements.

import numpy as np
import matplotlib.pylab as plt
from matplotlib.widgets import Button, CheckButtons
import time

plt.close('all')
fig,ax = plt.subplots()
ax.plot([1,2,3],[10,20,30],'bo-')
axcnt=0
plt.subplots_adjust(bottom=0.25)

axnext = plt.axes([0.81, 0.05, 0.1, 0.075]) #l,b,w,h
bnext = Button(axnext, 'Next')
nxtcnt=0

axchk = plt.axes([0.0, 0.05, 0.2, 0.125]) #l,b,w,h 
bchk = CheckButtons(axchk, ('Check',))
chkcnt=0

def on_press(event):
    global cancnt; cancnt += 1
    txt = plt.figtext(0.2,0.3,f"canvas clicked {cancnt}")
    fig.canvas.draw(); time.sleep(2); txt.remove(); fig.canvas.draw()
    
    
    if event.inaxes == ax:
        global axcnt; axcnt += 1
        txt = plt.figtext(0.4,0.0,f"ax clicked {axcnt}")
        fig.canvas.draw(); time.sleep(2); txt.remove(); fig.canvas.draw()
        
def on_next_button_clicked(event):
    global nxtcnt; nxtcnt += 1
    txt = plt.figtext(0.7,0.0, f"next button clicked {nxtcnt}")
    fig.canvas.draw(); time.sleep(2); txt.remove(); fig.canvas.draw()
    
def on_chk_button_clicked(event):
    global chkcnt; chkcnt += 1
    txt = plt.figtext(0.0,0.0, f"check button clicked {chkcnt}")
    fig.canvas.draw(); time.sleep(2); txt.remove(); fig.canvas.draw()

bnext.on_clicked(on_next_button_clicked)
bchk.on_clicked(on_chk_button_clicked)
            
fig.canvas.mpl_connect('button_press_event', on_press)
cancnt=0
txt = plt.figtext(0.2,0.9,f"test {cancnt}")

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.