Search code examples
python-3.xmatplotlibevent-handlingterminate

Refresh and close a plot by detecting key pressed


I have a simple loop plotting data read from a folder. It loops forever to update the plots and I want to end the program when I press ESC. So far, I wrote

fig = plt.figure()
plt.axes()

while True:
    ... # loop over data and plot
    plt.draw()
    plt.waitforbuttonpress(0)
    plt.cla()

If I close the figure by clicking on the X icon the program ends with an error. I can avoid the error by doing

    try:
        plt.waitforbuttonpress(0)
    except:
        break

But I would still like to be able to terminate the program by pressing ESC on the plot. Also, if I close the plot with CTRL+W the plot reappears. I tried adding an event detection, like

def parse_esc(event):
    if event.key == 'press escape':
        sys.exit(0)
fig.canvas.mpl_connect('key_press_event', parse_esc)

But it doesn't detect ESC. I tried with close_event instead of key_press_event but sys.exit(0) gives the following error

    while executing
"140506996271368filter_destroy 836 ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? 0 ?? ?? .140506996230464 17 ?? ?? ??"
    invoked from within
"if {"[140506996271368filter_destroy 836 ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? 0 ?? ?? .140506996230464 17 ?? ?? ??]" == "break"} break"
    (command bound to event)

I would also like to remove the loop and refresh the plot only if R is detected, but that's not so important.

Any help is appreciated, thanks.


Solution

  • If anyone will ever need to do something similar, here is what I did

    folder = ...
    
    def update():
        plt.cla()
        for f in os.listdir(folder):
            if f.endswith(".dat"):
                data = ... 
                plt.plot(data)
        plt.draw()
        print('refreshed')
    
    def handle(event):
        if event.key == 'r':
            update()
        if event.key == 'escape':
            sys.exit(0)
    
    fig = plt.figure()
    plt.axes()
    picsize = fig.get_size_inches() / 1.3
    fig.set_size_inches(picsize)
    fig.canvas.mpl_connect('key_press_event', handle)
    update()
    
    input('')