'How to block a python function until interaction with matplotlib is over

I wrote a python function that uses matplotlib to plot some data and measure user interaction. For simplicity's sake let's assume I want to count the number of times the user clicks on the plot:

from matplotlib import pyplot as plt


def count_clicks(data):
    fig, ax = plt.subplots()
    counter = 0
    done = False

    def onclick(event):
        nonlocal counter
        counter += 1

    def onclose(event):
        nonlocal counter
        nonlocal done
        print(counter)
        done = True

    ax.plot(data)
    fig.canvas.mpl_connect('button_press_event', onclick)
    fig.canvas.mpl_connect('close_event', onclose)

    return counter


count_clicks(range(10))

I would like the function to wait until the user closes the figure before returning, but currently, it's returning right away, leaving the figure detached (i.e. clicks are still counted, and when closing the figure the correct count is printed). What am I doing wrong?

I tried:

while not done:
    continue

before the return statement, which hanged the plot and didn't let it show. I also tried plt.show() and plt.ion() to no avail



Solution 1:[1]

Interactive mode appears to be turned on in your environment. You have to turn it off and force the draw with plt.show().

from matplotlib import pyplot as plt
plt.ioff()

def count_clicks(data):
    fig, ax = plt.subplots()
    counter = 0
    done = False

    def onclick(event):
        nonlocal counter
        counter += 1

    def onclose(event):
        nonlocal counter
        nonlocal done
        print(counter)
        done = True

    fig.canvas.mpl_connect('button_press_event', onclick)
    fig.canvas.mpl_connect('close_event', onclose)

    ax.plot(data)
    plt.show()

    return counter

count_clicks(range(10))

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Paul Brodersen