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

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

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

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

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

Ответы [ 16 ]

190 голосов
/ 19 января 2009

Используйте matplotlib звонки, которые не будут блокироваться:

Использование 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()

Использование интерактивного режима:

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()
120 голосов
/ 13 ноября 2012

Используйте ключевое слово «блок», чтобы переопределить поведение блокировки, например,

from matplotlib.pyplot import show, plot

plot(1)  
show(block=False)

# your code

, чтобы продолжить ваш код.

29 голосов
/ 19 января 2009

Лучше всегда проверять библиотеку, которую вы используете, поддерживает ли она использование неблокирующим способом.

Но если вам нужно более общее решение, или если нет другого пути, вы можете запустить все, что блокирует отдельный процесс, используя модуль multprocessing, включенный в python. Вычисление будет продолжено:

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

Это накладные расходы на запуск нового процесса, а иногда сложнее в отладке в сложных сценариях, поэтому я бы предпочел другое решение (используя matplotlib неблокирующие вызовы API )

21 голосов
/ 18 января 2013

Попробуйте

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

# Put
show()
# at the very end of your script
# to make sure Python doesn't bail out
# before you finished examining.

Документация show() гласит:

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

Один экспериментальный аргумент ключевого слова, block, может быть установлен на True или False для отмены описанного выше поведения блокировки.

10 голосов
/ 19 января 2009

Вы можете прочитать этот документ в документации matplotlib, озаглавленной:

Использование matplotlib в оболочке Python

8 голосов
/ 21 января 2009

В моем случае я хотел, чтобы во время вычисления вычислялось несколько окон. Для справки это так:

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. Очень полезное руководство по OO-интерфейсу matplotlib .

7 голосов
/ 08 марта 2017

ВАЖНО : Просто чтобы прояснить ситуацию. Я предполагаю, что команды находятся внутри .py скрипта, и скрипт вызывается, например, с помощью python script.py с консоли.

Простой способ, который работает для меня:

  1. Использовать block = False внутри шоу: plt.show (block = False)
  2. Используйте другой show () в конце скрипта .py.

Пример 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()

6 голосов
/ 11 ноября 2010

Что ж, у меня были большие проблемы с выяснением неблокирующих команд ... Но, наконец, мне удалось переработать пример " Cookbook / Matplotlib / Animations - Анимация выбранных элементов графика ", чтобы он работал с потоками () и передает данные между потоками либо через глобальные переменные, либо через многопроцессный Pipe) в Python 2.6.5 в Ubuntu 10.04.

Сценарий можно найти здесь: Animating_selected_plot_elements-thread.py - в противном случае вставляется ниже ( с меньшим количеством комментариев ) для справки:

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! 

Надеюсь, это кому-нибудь поможет,
Ура!

5 голосов
/ 18 января 2016

Если вы работаете в консоли, то есть IPython, вы можете использовать plt.show(block=False), как указано в других ответах. Но если вам лень, вы можете просто набрать:

plt.show(0)

Что будет таким же.

5 голосов
/ 18 декабря 2013

Во многих случаях удобнее, если сохранить изображение в виде файла .png на жестком диске. Вот почему:

Преимущества:

  • Вы можете открыть его, взглянуть на него и закрыть в любое время в процессе. Это особенно удобно, когда ваше приложение работает долго время.
  • Ничего не появляется, и вы не обязаны открывать окна. Это особенно удобно, когда вы имеете дело со многими фигурами.
  • Ваше изображение доступно для дальнейшего использования и не теряется при закрытии окна рисунка.

Минус:

  • Единственное, о чем я могу думать, - это то, что вам придется пойти и найти папку и открыть изображение самостоятельно.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...