Matplotlib - Force plot display and then return to main code

做~自己de王妃 提交于 2019-12-03 11:17:06

问题


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.

回答1:


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')



回答2:


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')



回答3:


I couldn't get this to work with Canopy (not yet at least) but I could get the code to run sort of like I wanted to using the Geany IDE. This is the code that works for me, it's a very minor modification to the first block of code in the question where the show() command is moved above from the end of the file to just below the make_plot() command:

from matplotlib.pyplot import plot, draw, show

def make_plot():
    plot([1,2,3])
    draw()
    print 'Plot displayed, waiting for it to be closed.'

print('Do something before plotting.')
# Now display plot in a window
make_plot()
# This line was moved up <----
show()

answer = raw_input('Back to main after plot window closed? ')
if answer == 'y':
    print('Move on')
else:
    print('Nope')

It doesn't do exactly what I want but it's close enough: it shows a plot to the user, waits till that plot window is closed and then moves on with the code. Ideally it shouldn't have to wait until the plot window is closed to move on with the code, but it's better than nothing I guess.

The code in the Add 2 section above also works in the same way and with no modifications needed in Geany, but I prefer this one because it's simpler. I'll update this answer If (when?) I get this to work with Canopy.



来源:https://stackoverflow.com/questions/17149646/matplotlib-force-plot-display-and-then-return-to-main-code

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!