from matplotlib import pyplot as p
from scipy import zeros
from Queue import Queue
import random
w,h = 320,200
black = zeros((h,w,3), dtype='uint8')
red = black.copy(); red[:,:,0] = 255
green = black.copy(); green[:,:,1] = 255
blue = black.copy(); blue[:,:,2] = 255
def ants():
from scipy import rand, dstack
return dstack([(255*rand(h,w)).astype('uint8')]*3)
fig = p.figure()
axs = [fig.add_subplot(1,3,i) for i in xrange(3)]
[ax.imshow(black) for ax in axs]
q = Queue()
def update_image(ax):
## this takes some time
import time
time.sleep(3)
ax.images[0].set_data(random.choice([red, green, blue]))
def hit(event):
if event.inaxes in axs:
update_axs = [event.inaxes]
else:
update_axs = axs
for ax in update_axs:
ax.images[0].set_data(ants())
p.draw()
# for ax in update_axs:
# update_image(ax)
# p.draw()
cid = fig.canvas.mpl_connect('button_press_event', hit)
p.show()
这是我的代码,这一切工作如预期。但是,当我取消事件处理程序中的这3行注释时,出现了一些我没有预料到的问题。首先,GUI冻结,而update_image
正在工作,其次,第一次调用draw()
似乎没有机会油漆,因为我没有看到赛车蚂蚁,而update_image
正在工作。在matplotlib中设置这种东西以使其顺利工作的更好方法是什么?
为了避免冻结GUI,您需要在单独的线程或进程中运行update_image
。使用threading
,您可以这样做:
import matplotlib
matplotlib.use('TkAgg')
from matplotlib import pyplot as p
from scipy import zeros
import random
import threading
w,h = 320,200
black = zeros((h,w,3), dtype='uint8')
red = black.copy(); red[:,:,0] = 255
green = black.copy(); green[:,:,1] = 255
blue = black.copy(); blue[:,:,2] = 255
def ants():
from scipy import rand, dstack
return dstack([(255*rand(h,w)).astype('uint8')]*3)
fig = p.figure()
axs = [fig.add_subplot(1,3,i) for i in xrange(3)]
[ax.imshow(black) for ax in axs]
def update_image(ax):
## this takes some time
import time
time.sleep(3)
ax.images[0].set_data(random.choice([red, green, blue]))
ax.figure.canvas.draw()
def hit(event):
if event.inaxes in axs:
update_axs = [event.inaxes]
else:
update_axs = axs
for ax in update_axs:
ax.images[0].set_data(ants())
p.draw()
for ax in update_axs:
t=threading.Thread(target=update_image,args=(ax,))
t.daemon=True
t.start()
cid = fig.canvas.mpl_connect('button_press_event', hit)
p.show()