1

I'm using python 3.7.7 and matplotlib 3.3.1 on Pycharm community 2020.1

I want to draw a figure and let the user decide if he likes that figure, by giving some console input. That means I need matplotlib to work in the interactive mode. I tried the following many approaches, that I've found online:

plt.ion() alone

import matplotlib.pyplot as plt
plt.ion()
plt.plot([1,2,3])
plt.show()


print('is this fig good? (y/n)')
x = input()
if x=="y":
    plt.savefig(r'C:\figures\papj.png')
else:
    print("big sad")

this results only in blank figure window. If you click that window too much, it will "stop responding".

plt.show(block=False)

import matplotlib.pyplot as plt    
plt.plot([1,2,3])
plt.show(block=False) 

print('is this fig good? (y/n)')
x = input()
if x=="y":
    plt.savefig(r'C:\figures\papj.png')
else:
    print("big sad")

Same result as previously.

plt.draw()

import matplotlib.pyplot as plt

plt.plot([1,2,3])
plt.draw()


print('is this fig good? (y/n)')
x = input()
if x=="y":
    plt.savefig(r'C:\figures\papj.png')
else:
    print("big sad")

This does nothing, just displays the question in the console.

plt.ion() and plt.draw()

import matplotlib.pyplot as plt
plt.ion()
plt.plot([1,2,3])
plt.draw()


print('is this fig good? (y/n)')
x = input()
if x=="y":
    plt.savefig(r'C:\figures\papj.png')
else:
    print("big sad")

Again, blank figure window, that crashes after clicking on it.

ion() and block=False

import matplotlib.pyplot as plt
plt.ion()
plt.plot([1,2,3])
plt.show(block=False)


print('is this fig good? (y/n)')
x = input()
if x=="y":
    plt.savefig(r'C:\figures\papj.png')
else:
    print("big sad")

Again, blank figure window, that crashes after clicking on it.

What can I do to make it work correctly?

user46147
  • 232
  • 1
  • 16

1 Answers1

1

You need to add a pause to avoid the figure being "locked" and to get to the user input while the Figure is still being displayed.

import matplotlib.pyplot as plt
plt.ion()
plt.plot([1,2,3])
plt.pause(0.01) # <---- add pause
plt.show()

print('is this fig good? (y/n)')
x = input()
if x=="y":
    plt.savefig(r'C:\figures\papj.png')
else:
    print("big sad")

If you want something more complicated than this, you would have a loop where you redraw the figure in each iteration (e.g. if you want to show a different figure) and pause right at the end of each iteration.

runDOSrun
  • 10,359
  • 7
  • 47
  • 57
  • I copied your code, and it looks that for my computer, value of pause equal to 0.01 is too small and results in just a black figure, that also crashes upon click. Changing the value to 1 fixed the problem, and now I have what I wanted. Thanks! – user46147 Sep 24 '20 at 10:07
  • On the other hand, the figure that appears, is clear, but not interactive. I cannot zoom or pan. It crashes when I try. Do you know how to solve it as well? – user46147 Sep 24 '20 at 10:13
  • @user46147 Hmm I'm not sure if that's even possible because `input` is blocking. If you look at similar [solutions](https://stackoverflow.com/a/33050617/860196), this is always the case I think. If you want something truly interactive, you could however abandon `input` and rather use [actual buttons](https://matplotlib.org/xkcd/examples/widgets/buttons.html) in your figure. You could also try changing matplotlib versions since people report different behavior (half your examples gave a different result for me). – runDOSrun Sep 24 '20 at 10:57