Python – Wait for the user to type in the Matplotlib Figure when a specific keyboard is pressed

Wait for the user to type in the Matplotlib Figure when a specific keyboard is pressed… here is a solution to the problem.

Wait for the user to type in the Matplotlib Figure when a specific keyboard is pressed

I want a user input and then stop the loop by pressing on a specific keyboard.

from __future__ import print_function
import sys
import numpy as np
import matplotlib.pyplot as plt

def press(event):
    print('press', event.key)
    sys.stdout.flush()
    if event.key == 'x':
       visible = xl.get_visible()
       xl.set_visible(not visible)
       fig.canvas.draw()
    if event.key == 'enter':
       cnt.append(1)

cnt=[]
List=[]
fig, ax = plt.subplots()

fig.canvas.mpl_connect('key_press_event', press)

ax.plot(np.random.rand(12), np.random.rand(12), 'go')
xl = ax.set_xlabel('easy come, easy go')
ax.set_title('Press a key')
plt.show()
plt.waitforbuttonpress() #non specific key press!!!

result=cnt[0]+cnt[1]

I want to stop the loop, wait for the user to hit enter, and then use cnt after to continue the code. However, if I don’t put plt.waitforbuttonpress(), the code will run and end, but if I put plt.waitforbuttonpress(), any keyboard or mouse press will run and end the entire code.

Solution

The code works the way I expected (matplotlib version 2.0.0 and TkAgg backend) you created a graph and it should block at the plt.show command.

If not, try matplotlib.use("TkAgg“) to change the backend (see order here)

Then you have a few options

1) Include the code you want to run in the event handling loop, either after an event you have or under a special key.

import numpy as np
import matplotlib.pyplot as plt

def press(event):
    print('press', event.key)
    if event.key == 'enter':
        cnt.append(1)
    if event.key == 'a':
        result = sum(cnt)
        print(result, cnt)

cnt=[]
fig, ax = plt.subplots()
fig.canvas.mpl_connect('key_press_event', press)
ax.plot(np.random.rand(12), np.random.rand(12), 'go')
plt.show()

When you press

A, you assume that you have pressed ENTER 8 times when you press ENTER.
(8, [1, 1, 1, 1, 1, 1, 1])

2) Add exit command exit graphic (you may need to come up with the best way to exit).

import numpy as np
import matplotlib.pyplot as plt

def press(event):
    print('press', event.key)
    if event.key == 'enter':
        cnt.append(1)
    if event.key == "escape":
        plt.close()

cnt=[]
fig, ax = plt.subplots()
fig.canvas.mpl_connect('key_press_event', press)
ax.plot(np.random.rand(12), np.random.rand(12), 'go')
plt.show()
result = sum(cnt)
print(result, cnt)

You should then run the command after plt.show().

3) Set a timeout for the event loop after which your code will run.

import numpy as np
import matplotlib.pyplot as plt

def press(event):
    print('press', event.key)
    if event.key == 'enter':
        cnt.append(1)

cnt=[]
fig, ax = plt.subplots()
fig.canvas.mpl_connect('key_press_event', press)
ax.plot(np.random.rand(12), np.random.rand(12), 'go')
plt.show(block=False)
plt.waitforbuttonpress()
plt.pause(5.)
result = sum(cnt)
print(result, cnt)

Looks like plt.waitforbuttonpress(time=5.) should do something similar, but I can’t get it to work.

Related Problems and Solutions