Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Matplotlib - Force plot display and then return to main code

Tags:

This is a MWE of what I'm after, adapted from this question:

from matplotlib.pyplot import plot, draw, show  def make_plot():     plot([1,2,3])     draw()     print 'continue computation'  print('Do something before plotting.') # Now display plot in a window make_plot()  answer = raw_input('Back to main and window visible? ') if answer == 'y':     print('Excellent') else:     print('Nope')  show() 

What I want is: I call the function to make the plot, the plot window appears, and then I get to go back to the prompt so I can input some value (based on that image that just displayed) and carry on with the code (the window can then close or remain there, I don't care).

What I get instead is that the window with the plot only appears after the code is completed, which is no good.


Add 1

I've tried the following with the same results, the plot window appears at the end of the code and not before:

from matplotlib.pyplot import plot, ion, draw  ion() # enables interactive mode plot([1,2,3]) # result shows immediately (implicit draw()) # at the end call show to ensure window won't close. draw()  answer = raw_input('Back to main and window visible? ') if answer == 'y':     print('Excellent') else:     print('Nope') 

The same happens if I change draw() for show().


Add 2

I've tried the following approach:

from multiprocessing import Process from matplotlib.pyplot import plot, show  def plot_graph(*args):     for data in args:         plot(data)     show()  p = Process(target=plot_graph, args=([1, 2, 3],)) p.start()  print 'computation continues...'  print 'Now lets wait for the graph be closed to continue...:' p.join() 

which results in a Python kernel has crashed error in Canopy with the message:

The kernel (user Python environment) has terminated with error code -6. This may be due to a bug in your code or in the kernel itself.  Output captured from the kernel process is shown below.  [IPKernelApp] To connect another client to this kernel, use: [IPKernelApp] --existing /tmp/tmp9cshhw.json QGtkStyle could not resolve GTK. Make sure you have installed the proper libraries. [xcb] Unknown sequence number while processing queue [xcb] Most likely this is a multi-threaded client and XInitThreads has not been called [xcb] Aborting, sorry about that. python: ../../src/xcb_io.c:274: poll_for_event: La declaración `!xcb_xlib_threads_sequence_lost' no se cumple. 

I should mention I'm running Canopy in elementary OS which is based in Ubuntu 12.04.


Add 3

Also tried solution posted in this question:

import numpy from matplotlib import pyplot as plt  if __name__ == '__main__':     x = [1, 2, 3]     plt.ion() # turn on interactive mode     for loop in range(0,3):         y = numpy.dot(x, loop)         plt.figure()         plt.plot(x,y)         plt.show()         _ = raw_input("Press [enter] to continue.") 

This displays empty plot windows as the code advances (ie: the user hits [enter]) and only displays the images after the code is finished.

This solution (also in the same question) doesn't even display the plot windows:

import numpy from matplotlib import pyplot as plt if __name__ == '__main__':     x = [1, 2, 3]     plt.ion() # turn on interactive mode, non-blocking `show`     for loop in range(0,3):         y = numpy.dot(x, loop)         plt.figure()   # create a new figure         plt.plot(x,y)  # plot the figure         plt.show()     # show the figure, non-blocking         _ = raw_input("Press [enter] to continue.") # wait for input from the user         plt.close()    # close the figure to show the next one. 
like image 358
Gabriel Avatar asked Jun 17 '13 14:06

Gabriel


2 Answers

You may use plt.show(block=False), which gets rid of the blocking directly.

For your example, this could read

from matplotlib.pyplot import plot, show  def make_plot():     plot([1,2,3])     show(block=False)     print('continue computation')  print('Do something before plotting.') # Now display plot in a window make_plot()  answer = input('Back to main and window visible? ') if answer == 'y':     print('Excellent') else:     print('Nope') 
like image 105
David Zwicker Avatar answered Sep 19 '22 22:09

David Zwicker


None of the presented solutions work for me. I tested them with three different IDEs PyCharm, Spyder and Pyzo, using the (currently) latest Matplotlib 2.1 under Python 3.6.

What works for me, although not optimal, is to use a plt.pause command:

import matplotlib.pyplot as plt  def make_plot():     plt.plot([1, 2, 3]) #    plt.show(block=False)  # The plot does not appear. #    plt.draw()             # The plot does not appear.     plt.pause(0.1)          # The plot properly appears.     print('continue computation')  print('Do something before plotting.') # Now display plot in a window make_plot()  answer = input('Back to main and window visible? ') if answer == 'y':     print('Excellent') else:     print('Nope') 
like image 38
divenex Avatar answered Sep 19 '22 22:09

divenex