Program Not Continuing After Closing Matplotlib Plot

  • user

    I can not confirm, that the selected solution from nosklo on 16:52 is working. For me draw does not open a window to display the plot, only the blocking show at the end displays the solution. However, his reply from 17:00 is correct. Switching interactive mode on via ion() fixes the problem.

    Reply

  • user

    if you are an advanced programmer, you can use os.fork() but keep in mind that using os.fork() can be tricky because you are creating a new process by copying the old process.

    Reply

  • user

    IMPORTANT: Just to make something clear. I assume that the commands are inside a .py script and the script is called using e.g. python script.py from the console.

    A simple way that works for me is:

    1. Use the block = False inside show : plt.show(block = False)
    2. Use another show() at the end of the .py script.

    Example of script.py file:

                    plt.imshow(*something*)                                                                plt.colorbar()                                                                              plt.xlabel("true ")                                                                    plt.ylabel("predicted ")                                                               plt.title(" the matrix")    # Add block = False                                            plt.show(block = False)  ################################ # OTHER CALCULATIONS AND CODE HERE ! ! ! ################################  # the next command is the last line of my script plt.show()                              

    Reply

  • user
                    plt.figure(1) plt.imshow(your_first_image)  plt.figure(2) plt.imshow(your_second_image)  plt.show(block=False) # That's important   raw_input("Press ENTER to exist") # Useful when you run your Python script from the terminal and you want to hold the running to see your figures until you press Enter                              

    Reply

  • user

    I had to also add plt.pause(0.001) to my code to really make it working inside a for loop (otherwise it would only show the first and last plot):

                    import matplotlib.pyplot as plt  plt.scatter([0], [1]) plt.draw() plt.show(block=False)  for i in range(10):     plt.scatter([i], [i+1])     plt.draw()     plt.pause(0.001)                              

    Reply

  • user

    In my opinion, the answers in this thread provide methods which don't work for every systems and in more complex situations like animations. I suggest to have a look at the answer of MiKTeX in the following thread, where a robust method has been found:
    How to wait until matplotlib animation ends?

    Reply

  • user

    If you are working in console, i.e. IPython you could use plt.show(block=False) as pointed out in the other answers. But if you're lazy you could just type:

                    plt.show(0)                              

    Which will be the same.

    Reply

  • user

    I also wanted my plots to display run the rest of the code (and then keep on displaying) even if there is an error (I sometimes use plots for debugging). I coded up this little hack so that any plots inside this with statement behave as such.

    This is probably a bit too non-standard and not advisable for production code. There is probably a lot of hidden "gotchas" in this code.

                    from contextlib import contextmanager  @contextmanager def keep_plots_open(keep_show_open_on_exit=True, even_when_error=True):     '''     To continue excecuting code when plt.show() is called     and keep the plot on displaying before this contex manager exits     (even if an error caused the exit).     '''     import matplotlib.pyplot     show_original = matplotlib.pyplot.show     def show_replacement(*args, **kwargs):         kwargs['block'] = False         show_original(*args, **kwargs)     matplotlib.pyplot.show = show_replacement      pylab_exists = True     try:         import pylab     except ImportError:          pylab_exists = False     if pylab_exists:         pylab.show = show_replacement      try:         yield     except Exception, err:         if keep_show_open_on_exit and even_when_error:             print "*********************************************"             print "Error early edition while waiting for show():"              print "*********************************************"             import traceback             print traceback.format_exc()             show_original()             print "*********************************************"             raise     finally:         matplotlib.pyplot.show = show_original         if pylab_exists:             pylab.show = show_original     if keep_show_open_on_exit:         show_original()  # *********************** # Running example # *********************** import pylab as pl import time if __name__ == '__main__':     with keep_plots_open():         pl.figure('a')         pl.plot([1,2,3], [4,5,6])              pl.plot([3,2,1], [4,5,6])         pl.show()          pl.figure('b')         pl.plot([1,2,3], [4,5,6])         pl.show()          time.sleep(1)         print '...'         time.sleep(1)         print '...'         time.sleep(1)         print '...'         this_will_surely_cause_an_error                              

    If/when I implement a proper "keep the plots open (even if an error occurs) and allow new plots to be shown", I would want the script to properly exit if no user interference tells it otherwise (for batch execution purposes).

    I may use something like a time-out-question "End of script! \nPress p if you want the plotting output to be paused (you have 5 seconds): " from https://stackoverflow.com/questions/26704840/corner-cases-for-my-wait-for-user-input-interruption-implementation.

    Reply

  • user

    If you want to open multiple figures, while keeping them all opened, this code worked for me:

                    show(block=False) draw()                              

    Reply

  • user

    My answer is a little off topic, but I just decided to get away from matplotlib in my application because of the problem that is stated in this question.

    Alternatively, you can use plotly. It does not block the process.

    Reply

  • user

    While not directly answering OPs request, Im posting this workaround since it may help somebody in this situation:

    • Im creating an .exe with pyinstaller since I cannot install python where I need to generate the plots, so I need the python script to generate the plot, save it as .png, close it and continue with the next, implemented as several plots in a loop or using a function.

    for this Im using:

                    import matplotlib.pyplot as plt #code generating the plot in a loop or function #saving the plot plt.savefig(var+'_plot.png',bbox_inches='tight', dpi=250)  #you can allways reopen the plot using os.system(var+'_plot.png') # unfortunately .png allows no interaction. #the following avoids plot blocking the execution while in non-interactive mode plt.show(block=False)  #and the following closes the plot while next iteration will generate new instance. plt.close()                              

    Where "var" identifies the plot in the loop so it wont be overwritten.

    Reply

  • user

    The OP asks about detatching matplotlib plots. Most answers assume command execution from within a python interpreter. The use-case presented here is my preference for testing code in a terminal (e.g. bash) where a file.py is run and you want the plot(s) to come up but the python script to complete and return to a command prompt.

    This stand-alone file uses multiprocessing to launch a separate process for plotting data with matplotlib. The main thread exits using the os._exit(1) mentioned in this post. The os._exit() forces main to exit but leaves the matplotlib child process alive and responsive until the plot window is closed. It's a separate process entirely.

    This approach is a bit like a Matlab development session with figure windows that come up with a responsive command prompt. With this approach, you have lost all contact with the figure window process, but, that's ok for development and debugging. Just close the window and keep testing.

    multiprocessing is designed for python-only code execution which makes it perhaps better suited than subprocess. multiprocessing is cross-platform so this should work well in Windows or Mac with little or no adjustment. There is no need to check the underlying operating system. This was tested on linux, Ubuntu 18.04LTS.

                    #!/usr/bin/python3  import time import multiprocessing import os  def plot_graph(data):     from matplotlib.pyplot import plot, draw, show     print("entered plot_graph()")     plot(data)     show() # this will block and remain a viable process as long as the figure window is open     print("exiting plot_graph() process")  if __name__ == "__main__":     print("starting __main__")     multiprocessing.Process(target=plot_graph, args=([1, 2, 3],)).start()     time.sleep(5)     print("exiting main")     os._exit(0) # this exits immediately with no cleanup or buffer flushing                              

    Running file.py brings up a figure window, then __main__ exits but the multiprocessing + matplotlib figure window remains responsive with zoom, pan, and other buttons because it is an independent process.

    Check the processes at the bash command prompt with:

    ps ax|grep -v grep |grep file.py

    Reply

  • user

    Use plt.show(block=False), and at the end of your script call plt.show().

    This will ensure that the window won't be closed when the script is finished.

    Reply

  • user

    It is better to always check with the library you are using if it supports usage in a non-blocking way.

    But if you want a more generic solution, or if there is no other way, you can run anything that blocks in a separated process by using the multprocessing module included in python. Computation will continue:

                    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 'yay' print 'computation continues...' print 'that rocks.'  print 'Now lets wait for the graph be closed to continue...:' p.join()                              

    That has the overhead of launching a new process, and is sometimes harder to debug on complex scenarios, so I'd prefer the other solution (using matplotlib's nonblocking API calls)

    Reply

  • user

    Use matplotlib's calls that won't block:

    Using draw():

                    from matplotlib.pyplot import plot, draw, show plot([1,2,3]) draw() print('continue computation')  # at the end call show to ensure window won't close. show()                              

    Using interactive mode:

                    from matplotlib.pyplot import plot, ion, show ion() # enables interactive mode plot([1,2,3]) # result shows immediatelly (implicit draw())  print('continue computation')  # at the end call show to ensure window won't close. show()                              

    Reply

  • user

    You may want to read this document in matplotlib's documentation, titled:

    Using matplotlib in a python shell

    Reply

  • user

    In my case, I wanted to have several windows pop up as they are being computed. For reference, this is the way:

                    from matplotlib.pyplot import draw, figure, show f1, f2 = figure(), figure() af1 = f1.add_subplot(111) af2 = f2.add_subplot(111) af1.plot([1,2,3]) af2.plot([6,5,4]) draw()  print 'continuing computation' show()                              

    PS. A quite useful guide to matplotlib's OO interface.

    Reply

  • user

    In many cases it is more convenient til save the image as a .png file on the hard drive. Here is why:

    Advantages:

    • You can open it, have a look at it and close it down any time in the process. This is particularly convenient when your application is running for a long
      time.
    • Nothing pops up and you are not forced to have the windows open. This is particularly convenient when you are dealing with many figures.
    • Your image is accessible for later reference and is not lost when closing the figure window.

    Drawback:

    • The only thing I can think of is that you will have to go and finder the folder and open the image yourself.

    Reply

  • user

    Use the keyword 'block' to override the blocking behavior, e.g.

                    from matplotlib.pyplot import show, plot  plot(1)   show(block=False)  # your code                              

    to continue your code.

    Reply

  • user

    Try

                    import matplotlib.pyplot as plt plt.plot([1,2,3]) plt.show(block=False) # other code # [...]  # Put plt.show() # at the very end of your script to make sure Python doesn't bail out # before you finished examining.                              

    The show() documentation says:

    In non-interactive mode, display all figures and block until the figures have been closed; in interactive mode it has no effect unless figures were created prior to a change from non-interactive to interactive mode (not recommended). In that case it displays the figures but does not block.

    A single experimental keyword argument, block, may be set to True or False to override the blocking behavior described above.

    Reply

  • user

    On my system show() does not block, although I wanted the script to wait for the user to interact with the graph (and collect data using 'pick_event' callbacks) before continuing.

    In order to block execution until the plot window is closed, I used the following:

                    fig = plt.figure() ax = fig.add_subplot(1,1,1) ax.plot(x,y)  # set processing to continue when window closed def onclose(event):     fig.canvas.stop_event_loop() fig.canvas.mpl_connect('close_event', onclose)  fig.show() # this call does not block on my system fig.canvas.start_event_loop_default() # block here until window closed  # continue with further processing, perhaps using result from callbacks                              

    Note, however, that canvas.start_event_loop_default() produced the following warning:

                    C:\Python26\lib\site-packages\matplotlib\backend_bases.py:2051: DeprecationWarning: Using default event loop until function specific to this GUI is implemented   warnings.warn(str,DeprecationWarning)                              

    although the script still ran.

    Reply

  • user

    Well, I had great trouble figuring out the non-blocking commands… But finally, I managed to rework the "Cookbook/Matplotlib/Animations – Animating selected plot elements" example, so it works with threads (and passes data between threads either via global variables, or through a multiprocess Pipe ) on Python 2.6.5 on Ubuntu 10.04.

    The script can be found here: Animating_selected_plot_elements-thread.py – otherwise pasted below (with fewer comments) for reference:

                    import sys import gtk, gobject import matplotlib matplotlib.use('GTKAgg') import pylab as p import numpy as nx  import time  import threading     ax = p.subplot(111) canvas = ax.figure.canvas  # for profiling tstart = time.time()  # create the initial line x = nx.arange(0,2*nx.pi,0.01) line, = ax.plot(x, nx.sin(x), animated=True)  # save the clean slate background -- everything but the animated line # is drawn and saved in the pixel buffer background background = canvas.copy_from_bbox(ax.bbox)   # just a plain global var to pass data (from main, to plot update thread) global mypass  # http://docs.python.org/library/multiprocessing.html#pipes-and-queues from multiprocessing import Pipe global pipe1main, pipe1upd pipe1main, pipe1upd = Pipe()   # the kind of processing we might want to do in a main() function, # will now be done in a "main thread" - so it can run in # parallel with gobject.idle_add(update_line) def threadMainTest():     global mypass     global runthread     global pipe1main      print "tt"      interncount = 1      while runthread:          mypass += 1         if mypass > 100: # start "speeding up" animation, only after 100 counts have passed             interncount *= 1.03         pipe1main.send(interncount)         time.sleep(0.01)     return   # main plot / GUI update def update_line(*args):     global mypass     global t0     global runthread     global pipe1upd      if not runthread:         return False       if pipe1upd.poll(): # check first if there is anything to receive         myinterncount = pipe1upd.recv()      update_line.cnt = mypass      # restore the clean slate background     canvas.restore_region(background)     # update the data     line.set_ydata(nx.sin(x+(update_line.cnt+myinterncount)/10.0))     # just draw the animated artist     ax.draw_artist(line)     # just redraw the axes rectangle     canvas.blit(ax.bbox)      if update_line.cnt>=500:         # print the timing info and quit         print 'FPS:' , update_line.cnt/(time.time()-tstart)          runthread=0         t0.join(1)            print "exiting"         sys.exit(0)      return True    global runthread  update_line.cnt = 0 mypass = 0  runthread=1  gobject.idle_add(update_line)  global t0 t0 = threading.Thread(target=threadMainTest) t0.start()   # start the graphics update thread p.show()  print "out" # will never print - show() blocks indefinitely!                              

    Hope this helps someone,
    Cheers!

    Reply

  • cbd gummies

    Good Afternoon everyone ! can anyone recommend where I can buy Pachamama CBD Softgels Full Spectrum Vegan Capsules 25mg?

    Reply

  • Armani

    Does anyone know what happened to Dimepiece LA celebrity streetwear brand? I cannot check out on Dimepiecela site. I've read in Vogue that they were acquired by a UK-based hedge fund in excess of $50 million. I have just bought the Meditate Yoga Bag from Ebay and totally love it xox

    Reply

  • Pierina

    how much cbd vape is too much

    Reply

  • grossmanhaideatel.blogspot.com

    Source: https://www.techtalk7.com/is-there-a-way-to-detach-matplotlib-plots-so-that-the-computation-can-continue/

    0 Response to "Program Not Continuing After Closing Matplotlib Plot"

    Post a Comment

    Iklan Atas Artikel

    Iklan Tengah Artikel 1

    Iklan Tengah Artikel 2

    Iklan Bawah Artikel