AaylaSecura
AaylaSecura

Reputation: 43

Conditional Button-press-event in matplotlib

I'm trying to write a piece of code that will only run a button-click-event if a checkbox is checked.

In more detail, the button-press-event records the mouse click coordinates and plots a vertical red line on the plot at the clicked coordinates. However, I only want this to run if the check box 'On' is checked.

Can anyone help me fix the following code?

import numpy as np
import matplotlib.pyplot as plt
from matplotlib.widgets import CheckButtons
import ipywidgets as widgets
from ipywidgets import interactive

#mouse click function to store coordinates and plot vertical red line
def onclick(event):
    if event == 'On':
        global ix,iy
        ix, iy = event.xdata, event.ydata

        global click_count
        click_count.append((ix,iy))

        #plotting lines where clicks occur
        if len(click_count) > 1:
            ax1.axvline(x=ix, ymin=0, ymax=1, color = "red")

        # assign global variable to access outside of function
        global coords3
        coords3.append((ix, iy))


        # Disconnect after 12 clicks
        if len(coords3) == 12:
            fig.canvas.mpl_disconnect(cid)
            plt.close(1)
        return

#check box function
def func(label):
    if label == 'On':
        return 'On'

#plots the graph

x = range(0,10)
y = range(0,10)

fig = plt.figure(1)
ax1 = fig.add_subplot(111)
ax1.plot(x,y, color = "blue")
ax1.set_title('This is my graph')

#create the check box
ax2 = plt.axes([0.7, 0.05, 0.1, 0.075])
check_box= CheckButtons(ax2, ('On', 'Off'), (False, False))

#define check box function
check = check_box.on_clicked(func)

# calling out the click coordinates to a variable
coords3 = []
click_count = []


# Call click func
cid = fig.canvas.mpl_connect('button_press_event', onclick(check))

plt.show(1)

Upvotes: 1

Views: 5305

Answers (1)

ImportanceOfBeingErnest
ImportanceOfBeingErnest

Reputation: 339112

I would think that the following is roughly what this question asks about. There are a lot of problems with the code from the question, I think I cannot comment on all of them, but some major ones are:

  • You cannot call the callback function already when registering it. And you cannot simply use some custom argument. The argument for the matplotlib events are Events.
  • You will need to query if the checkbox is being checked or not within the callback function.
  • You need to draw the canvas if a new red line is to be shown.
  • For a binary state toggle a single checkbox is sufficient. Else it becomes really complicated.
  • You will need to check if the click actually happened within the axes. This also requires that the checkbox is not within the axes, else a click on the checkbox would also produce a line.

Complete code.

import matplotlib.pyplot as plt
from matplotlib.widgets import CheckButtons

#mouse click function to store coordinates and plot vertical red line
def onclick(event):
    # Only use event within the axes.
    if not event.inaxes == ax1:
        return
    # Check if Checkbox is "on"
    if check_box.get_status()[0]:

        ix, iy = event.xdata, event.ydata

        coords3.append((ix,iy))

        #plotting lines where clicks occur
        if len(coords3) >= 1:
            ax1.axvline(x=ix, ymin=0, ymax=1, color = "red")
            fig.canvas.draw_idle()
        # Disconnect after 12 clicks
        if len(coords3) >= 12:
            fig.canvas.mpl_disconnect(cid)
            plt.close(fig)

#plots the graph
x = range(0,10)
y = range(0,10)

fig, ax1 = plt.subplots()
ax1.plot(x,y, color = "blue")
ax1.set_title('This is my graph')

#create the check box
ax2 = plt.axes([0.7, 0.05, 0.1, 0.075])
check_box = CheckButtons(ax2, ['On',], [False,])

# List to store coordinates
coords3 = []

# Callback to click func
cid = fig.canvas.mpl_connect('button_press_event', onclick)

plt.show()

print(coords3)

Upvotes: 1

Related Questions