有没有办法分离matplotlib图,以便计算可以继续?

met*_*ore 242 python plot matplotlib

在Python解释器中的这些指令之后,获得一个带有绘图的窗口:

from matplotlib.pyplot import *
plot([1,2,3])
show()
# other code
Run Code Online (Sandbox Code Playgroud)

不幸的是,我不知道如何继续以交互方式探索show()在程序进行进一步计算时创建的图形.

有可能吗?有时计算很长,如果他们在检查中间结果期间继续进行计算会有所帮助.

nos*_*klo 205

使用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()
Run Code Online (Sandbox Code Playgroud)

使用交互模式:

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()
Run Code Online (Sandbox Code Playgroud)

  • `draw()`对我不起作用,它不会打开任何窗口.但是使用`show(block = False)`而不是`draw()`似乎可以在matplotlib 1.1中使用. (105认同)
  • 使用matplotlib 0.98.3,右侧导入来自matplotlib.pyplot导入图,绘图,显示 (28认同)
  • `draw()`对我来说也不起作用,只有`暂停(0.001)`做了:/sf/ask/1978841021/ (9认同)
  • @nosklo,你看到了吗?你把它变成了python [tutorial](http://www.scribd.com/doc/47168316/45/Nonblocking-Plots-with-Matplotlib) (4认同)
  • @noskolo如果我有几个数字,如何绘制并显示Fig1,同时继续后台继续?我希望这个数字一直打开,直到生成下一个图,所以最后我打开所有无花果并完成代码.使用您当前的解决方案,它让我等待关闭图1然后代码继续.谢谢!! (3认同)
  • 这个解决方案对我不起作用。根本没有绘制任何内容。 (2认同)

Jan*_*Jan 123

使用关键字"block"来覆盖阻止行为,例如

from matplotlib.pyplot import show, plot

plot(1)  
show(block=False)

# your code
Run Code Online (Sandbox Code Playgroud)

继续你的代码.

  • 但这会立即关闭情节窗口,不会让情节保持打开状态. (11认同)
  • 是的,如果从命令行调用脚本,那就是这样.如果您在Ipython shell中,则不会关闭窗口. (7认同)
  • 检查 @Nico 的答案,了解在一般情况下使窗口保持打开状态的技巧。 (2认同)
  • 对我来说,这不会立即关闭窗口,只有在脚本完成时才关闭(因此,如果您希望它保持打开状态,可以在脚本末尾手动阻止)。 (2认同)
  • 是的,当脚本退出时,非阻塞窗口将关闭。您可以(a)允许阻塞最后一个绘图,或者(b)不退出脚本(也许要求输入:“按 <Enter> 退出绘图”或类似的内容)。 (2认同)

nos*_*klo 29

如果它以非阻塞方式支持使用,最好始终检查您正在使用的库.

但是如果你想要一个更通用的解决方案,或者没有其他办法,你可以使用multprocessingpython中包含的模块运行任何阻塞在一个单独进程中的东西.计算将继续:

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()
Run Code Online (Sandbox Code Playgroud)

这已推出一个新的进程的开销,有时难以在复杂的场景进行调试,所以我更喜欢其他的解决方案(使用matplotlib非阻塞API调用)


Nic*_*mer 23

尝试

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.
Run Code Online (Sandbox Code Playgroud)

show()文件说:

在非交互模式下,显示所有数字并阻止,直到数字关闭; 在交互模式下,除非在从非交互模式更改为交互模式之前创建数字(不推荐),否则它无效.在这种情况下,它显示数字但不阻止.

可以将单个实验关键字参数show()设置为show()show()覆盖上述阻塞行为.


mak*_*kis 11

重要提示:只是为了说清楚.我假设命令在.py脚本中,并且例如python script.py从控制台调用脚本.

一个适合我的简单方法是:

  1. 在show:plt.show中使用block = False (block = False)
  2. 在.py脚本的末尾使用另一个 show().

script.py文件示例:

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()
Run Code Online (Sandbox Code Playgroud)


nos*_*klo 10

您可能希望在文档中阅读本matplotlib文档,标题为:

在python shell中使用matplotlib


met*_*ore 8

在我的情况下,我想在计算时弹出几个窗口.作为参考,这是方式:

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()
Run Code Online (Sandbox Code Playgroud)

PS.matplotlib的OO接口非常有用的指南.


sda*_*aau 6

好吧,我很难搞清楚非阻塞命令.​​.....但最后,我设法重做了" Cookbook/Matplotlib/Animations - 动画选定的绘图元素 "示例,因此它适用于线程(并在线程之间传递数据)通过全局变量,或通过多Pipe进程)在Ubuntu 10.04上的Python 2.6.5上.

脚本可以在这里找到: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! 
Run Code Online (Sandbox Code Playgroud)

希望这有助于某人,
干杯!


elg*_*lge 5

在许多情况下,将图像保存为硬盘驱动器上的.png文件更方便.原因如下:

好处:

  • 您可以打开它,查看它并在此过程中随时关闭它.当您的应用程序运行很长时间时,这非常方便.
  • 没有任何东西弹出,你不会被迫打开窗户.当你处理许多数字时,这是特别方便的.
  • 您的图像可供以后参考,关闭图形窗口时不会丢失.

退税:

  • 我唯一能想到的是你必须自己去查找文件夹并打开图像.

  • 退缩png不是互动的:\ (5认同)

Ant*_*pov 5

如果您在控制台中工作,即IPython您可以plt.show(block=False)在其他答案中指出.但如果你很懒,你可以输入:

plt.show(0)
Run Code Online (Sandbox Code Playgroud)

哪个都一样.


Mar*_*cka 5

我还必须添加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)
Run Code Online (Sandbox Code Playgroud)