Capy
Capy

Reputation: 65

PyCharm matplotlib interactive figures without blocking execution

I read a lot of stack overflow questions regarding this topics but after a lot of experiment I can't figure out my problem.

I use PyCharm 2016.3.2 on Windows 7 (but I have the same issue on OSX), my interpreter is the last version of Anaconda with Python 3.6 and matplotlib 2.0.0.

Here is what I try to achieve (and maybe I am not using the right approach because I am trying to recreate the behavior I am use to in Octave/Matlab) :

  1. Plot one figure in a popup windows
  2. Pause my script (input("press a key to continue"))
  3. Observe the figure, then press a key to continue the script
  4. Compute something else
  5. Plot new data on the same figure
  6. Pause my script (input("press a key to continue"))
  7. Observe the figure, then press a key to continue the script

Here is my test code :

import matplotlib
matplotlib.use('TkAgg')
import matplotlib.pyplot as plt

print('Plotting Data...')

plt.ion()
plt.figure(1)
plt.plot([1, 5, 10, 20], [1, 5, 10, 20])
plt.xlabel('x label')
plt.ylabel('y label')
plt.show()
plt.pause(0.0001)

input('Plotting Data done..., Press a key to continue')

plt.figure(1)
plt.plot([1, 5, 10, 20], [2, 10, 20, 40])
plt.show()
plt.pause(0.0001)

input('Program paused. Press enter to end.\n')

This is the closest version of what I want, the plots are correct but not responsive when I mouse over them (plt.pause(0.0001) generates a warning but code works).

I played a lot with parameters (plt.ion() ; plt.pause() ; plt.show(block=False)). Most of the time, this led to empty plot windows or I needed to close the window to continue the execution.

Thanks for your help !

Upvotes: 3

Views: 5230

Answers (1)

ImportanceOfBeingErnest
ImportanceOfBeingErnest

Reputation: 339570

Once plt.show() is called the main loop is taken over by the Window. Therefore, as soon as input get's called, the main loop becomes unresponsive.

You could try to stay in the GUI loop and handle the key press there.

import matplotlib
matplotlib.use('TkAgg')
import matplotlib.pyplot as plt

print('Plotting Data...')

fig, ax = plt.subplots()
ax.set_xlabel('x label')
ax.set_ylabel('y label')
i=[0]

def f1():
    ax.plot([1, 5, 10, 20], [1, 5, 10, 20])

def f2():
    ax.plot([1, 5, 10, 20], [2, 10, 20, 40])

def f3():
    ax.plot([1, 5, 10, 20], [5, 9, 17, 28])


def update(event=None):
    if i[0]==0: f1()
    if i[0]==1: f2()
    if i[0]==2: f3()
    fig.canvas.draw_idle()
    i[0]+=1
    print('Step {} done..., Press a key to continue'.format(i[0]))

fig.canvas.mpl_connect("key_press_event", update)    

update()
plt.show()

Upvotes: 0

Related Questions