1

I am making a program with different modules, components to perform file/folder management, data acquisition, model computation, and online acquisition feedback with OpenCV. The program uses a very simple command-line interface, which core is a menu where the user can input a number from 1 to X to start the task described.

[IN] Available options:
     | 1 - Do something
     | 2 - Run acquisition
     | 3 - Compute model
     | 4 - Start something else
     | 5 - Open cv2 windows
     | 6 - Quit

The compute model function called when the user input 3 ends with a matplotlib plot to let the user assess the correctness of the model.

My problem is that the plot shows up only at the program end, i.e. after the user inputs 6 to quit. The plot will not show up before, even if I add a plt.show() or f.show() with or without block=False.

Is there a way to get matplotlib to show the figure as soon as possible, or even to wait until matplotlib shows the figure without having to execute this plot/model computation in a separate thread/process?

Reproducible example:

from matplotlib import pyplot as plt

def input_menu(options, retries=3):
    print ('Available options:')
    for key, value in options.items():
        print (f"    {key} - {value}")
    
    selection = int(input('[IN] What do you want to do ? '))
    return selection
    
while True:
    selection = input_menu(options={1: 'Plot',
                                    2: 'Quit'})
    
    if selection == 1:
        f, ax = plt.subplots(1, 1, figsize=(10, 10))
        ax.plot([1, 2, 3])
        
    elif selection == 2:
        break
    
    else:
        break

Press 1; the menu will prompt again and the plot should appear. The plot will not appear until 2 is pressed and the program is completed. I am using spyder as an IDE. In spyder, the backend PyQT5 is selected.

As you suggested, I tried also with another backend, i.e. I used python test.py in the terminal. This time the plot does show up as expected after 1 is pressed. No need to wait for the program to complete.

Mathieu
  • 5,410
  • 6
  • 28
  • 55
  • Some backends require to add `plt.ion()` for the interactive feature to be turned on, some require that `plt.wait(0.01)` is inserted into the update loop. Depends on the environment what works and what not. – Mr. T Dec 22 '20 at 10:40
  • @Mr.T I already used plt.ion() once, and in this case it's a bit different. There is no update loop either. At the end of the function 'compute model' called by pressing the '3', a single plot is produced. There are no updates added to that plot, and I would simply like to get it to display. – Mathieu Dec 22 '20 at 10:45
  • Difficult to understand then why function 3 would not show the generated graph, especially because this problem is not reproducible by any SO user. Does the problem persist if you replace the plotting routine with a simple `ax.plot([1,3,2])`? If so, could you boil down your problem to the input routine and this simple plot and provide it as an MCVE? As it is now, your question seems to have too much and not enough information. Another thing worth trying is to test if the problem is backend-dependent. – Mr. T Dec 22 '20 at 11:05
  • 1
    @Mr.T Edited with an MCVE. As you suggested, it seems to be a backend problem, as if run from the terminal it works fine. – Mathieu Dec 22 '20 at 12:32

0 Answers0