Есть ли способ отсоединить графики matplotlib, чтобы вычисления могли продолжаться? - PullRequest
232 голосов
/ 19 января 2009

После этих инструкций в интерпретаторе Python появляется окно с графиком:

from matplotlib.pyplot import *
plot([1,2,3])
show()
# other code

К сожалению, я не знаю, как продолжать интерактивно исследовать фигуру, созданную show(), пока программа выполняет дальнейшие вычисления.

Возможно ли это вообще? Иногда расчеты длинные, и было бы полезно, если бы они продолжались при проверке промежуточных результатов.

Ответы [ 16 ]

3 голосов
/ 09 ноября 2016

Мне также пришлось добавить plt.pause(0.001) к моему коду, чтобы он действительно работал внутри цикла for (иначе он отображал бы только первый и последний график):

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)
3 голосов
/ 04 ноября 2014

Я также хотел, чтобы мои графики отображали выполнение остальной части кода (а затем продолжали отображаться), даже если есть ошибка (я иногда использую графики для отладки). Я запрограммировал этот маленький хак, чтобы все графики внутри этого оператора with вели себя так.

Это, вероятно, слишком нестандартно и не рекомендуется для производственного кода. В этом коде, вероятно, много скрытых "ошибок".

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

Если / когда я реализую правильное «держать графики открытыми (даже если возникает ошибка) и разрешать показ новых графиков», я бы хотел, чтобы скрипт корректно завершился, если пользовательское вмешательство не сообщит ему иначе (для пакетного выполнения цели).

Я могу использовать что-то вроде тайм-аута "Конец сценария! \ NНажмите p, если вы хотите, чтобы вывод печати был приостановлен (у вас есть 5 секунд):" с https://stackoverflow.com/questions/26704840/corner-cases-for-my-wait-for-user-input-interruption-implementation.

2 голосов
/ 21 февраля 2017
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
2 голосов
/ 17 марта 2011

В моей системе show () не блокируется, хотя я хотел, чтобы скрипт продолжал ждать, пока пользователь взаимодействует с графиком (и собирает данные с помощью обратных вызовов 'pick_event'), прежде чем продолжить.

Чтобы заблокировать выполнение до закрытия окна графика, я использовал следующее:

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

Обратите внимание, однако, что canvas.start_event_loop_default () выдает следующее предупреждение:

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)

хотя скрипт все еще работал.

1 голос
/ 27 декабря 2015

По моему мнению, ответы в этой теме предоставляют методы, которые не работают для каждой системы и в более сложных ситуациях, таких как анимация. Я предлагаю взглянуть на ответ MiKTeX в следующей ветке, где найден надежный метод: Как дождаться окончания анимации matplotlib?

0 голосов
/ 16 сентября 2016

Если вы хотите открыть несколько фигур, оставив их открытыми, этот код работает для меня:

show(block=False)
draw()
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...