在Python解释器中执行这些指令后,就会得到一个带有绘图的窗口:
from matplotlib.pyplot import *
plot([1,2,3])
show()
# other code
不幸的是,我不知道如何在程序继续计算时继续交互式地探索show()
创建的图形。
这种情况有可能吗?有时候计算需要很长时间,如果在检查中间结果的同时能够继续进行计算将会很有帮助。
在Python解释器中执行这些指令后,就会得到一个带有绘图的窗口:
from matplotlib.pyplot import *
plot([1,2,3])
show()
# other code
不幸的是,我不知道如何在程序继续计算时继续交互式地探索show()
创建的图形。
这种情况有可能吗?有时候计算需要很长时间,如果在检查中间结果的同时能够继续进行计算将会很有帮助。
使用不会阻塞的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()
draw()
对我没用,它没有打开任何窗口。然而,在 matplotlib 1.1 中使用 show(block=False)
替代 draw()
似乎能解决问题。 - rumpeldraw()
对我也没有用,只有 pause(0.001)
有用:https://dev59.com/n14c5IYBdhLWcg3wJnU- - NumesSanguisfrom matplotlib.pyplot import show, plot
plot(1)
show(block=False)
# your code
继续编写您的代码。
如果你想在非阻塞的情况下使用某个库,最好始终与你正在使用的库进行确认。
但是如果你需要更通用的解决方案,或者没有其他方法,可以使用Python中包含的multiprocessing
模块在单独的进程中运行任何阻塞的内容。计算将会继续:
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 调用)。
if __name__ == '__main__':
了吗? - Wernight尝试
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.
show()
文档 说:
在非交互模式下,显示所有图像并阻塞直到图像被关闭;在交互模式下,除非图像是在从非交互模式更改为交互模式之前创建的(不推荐),否则没有任何效果。在这种情况下,它会显示图像但不会阻塞。
一个实验性的关键字参数 block 可以设置为True或False,以覆盖上述的阻止行为。
重要提示:为了澄清一些问题,我假设命令是在一个.py
脚本中,然后使用例如 python script.py
从控制台调用该脚本。
一个对我有效的简单方法是:
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()
matplotlib
文档中的这篇文章,标题为:“在 Python Shell 中使用 matplotlib”。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. 一份非常有用的matplotlib面向对象接口指南。
我曾经在非阻塞命令方面遇到了很大的困难......但最终,我成功地重构了Cookbook/Matplotlib/Animations - Animating selected plot elements示例,使其能够在Python 2.6.5和Ubuntu 10.04上使用线程(并通过全局变量或通过多进程Pipe
传递数据)。
该脚本可以在此处找到: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!
plt.show(block=False)
。但如果你很懒惰,你可以只是输入:plt.show(0)
将是相同的。
ion()
打开交互模式可以解决问题。 - H. Brandsmeieros.fork()
,但请记住,使用os.fork()
可能会很棘手,因为您正在通过复制旧进程来创建新进程。 - Trevor Boyd Smithos.fork
方法。 - Redsbefall