Python 为什么matplotlib只需要在主线程中打印?
我正试图绘出一台发电机的输出 以下代码按预期工作(Ctrl-C终止执行): 但是,如果我将绘图放在线程中,则会得到Python 为什么matplotlib只需要在主线程中打印?,python,multithreading,python-2.7,matplotlib,plot,Python,Multithreading,Python 2.7,Matplotlib,Plot,我正试图绘出一台发电机的输出 以下代码按预期工作(Ctrl-C终止执行): 但是,如果我将绘图放在线程中,则会得到运行时错误:主线程不在主循环中: import numpy as np import pylab as p from Queue import Queue from threading import Thread import time def dataGenerator(): while True: yield np.random.random() de
运行时错误:主线程不在主循环中
:
import numpy as np
import pylab as p
from Queue import Queue
from threading import Thread
import time
def dataGenerator():
while True:
yield np.random.random()
def plotter():
while True:
data = q.get()
x = data[0]
y = data[1]
p.plot(x,y,'o')
p.draw()
print x,y
q.task_done()
q = Queue()
p.figure(); p.hold(True); p.show(block=False)
plotThread = Thread(target=plotter)
plotThread.daemon = True
plotThread.start()
f = dataGenerator()
while True:
x = f.next()
y = f.next()
q.put([x,y])
plotThread.join()
为什么matplotlib
关心哪个线程进行打印
编辑:我不是问如何解决这个问题,而是问为什么会发生这种情况。可能是您用于后端的GUI。GUI可能希望在主线程中找到自己,但当matplotlib调用
get\u current\u fig\u manager().canvas.draw()
时就不是这样了
例如,当我这样做时,我得到以下回溯:
Exception in thread Thread-1:
Traceback (most recent call last):
File "/usr/lib/python2.7/threading.py", line 810, in __bootstrap_inner
self.run()
File "/usr/lib/python2.7/threading.py", line 763, in run
self.__target(*self.__args, **self.__kwargs)
File "tmp.py", line 18, in plotter
p.draw()
File "/usr/lib/pymodules/python2.7/matplotlib/pyplot.py", line 555, in draw
get_current_fig_manager().canvas.draw()
File "/usr/lib/pymodules/python2.7/matplotlib/backends/backend_tkagg.py", line 349, in draw
tkagg.blit(self._tkphoto, self.renderer._renderer, colormode=2)
File "/usr/lib/pymodules/python2.7/matplotlib/backends/tkagg.py", line 13, in blit
tk.call("PyAggImagePhoto", photoimage, id(aggimage), colormode, id(bbox_array))
RuntimeError: main thread is not in main loop
注意tk.call(…)
行。您得到的异常不是从matplotlib引发的,而是从TkInter引发的
为什么matplotlib关心哪个线程进行打印?
我不是问如何解决这个问题,而是问为什么会发生这种情况
@Evert是对的,它不是matplotlib,而是您的GUI工具包(matplotlib用于为您创建带有绘图的窗口的后端之一)。发生这种情况是因为GUI工具包是事件驱动的(您不希望用户界面出现阻塞行为,对吧?),并且它们具有控制程序执行的内部事件循环。其思想是,事件由事件循环监视并分派给回调。要做到这一点,事件循环应该在主线程中启动,而长时间运行任务的回调则被移动到单独的线程中。那么为什么TkInter关心绘图是否在主循环中?@Sparkler您自己使用的gui/后端是什么?默认值,我猜是TkInter。@Sparkler在这种情况下,你可能想看看这里的其他东西。或者通读一篇关于这个的文章。我不是问如何解决这个问题,而是问为什么会发生这种情况。可能的重复
Exception in thread Thread-1:
Traceback (most recent call last):
File "/usr/lib/python2.7/threading.py", line 810, in __bootstrap_inner
self.run()
File "/usr/lib/python2.7/threading.py", line 763, in run
self.__target(*self.__args, **self.__kwargs)
File "tmp.py", line 18, in plotter
p.draw()
File "/usr/lib/pymodules/python2.7/matplotlib/pyplot.py", line 555, in draw
get_current_fig_manager().canvas.draw()
File "/usr/lib/pymodules/python2.7/matplotlib/backends/backend_tkagg.py", line 349, in draw
tkagg.blit(self._tkphoto, self.renderer._renderer, colormode=2)
File "/usr/lib/pymodules/python2.7/matplotlib/backends/tkagg.py", line 13, in blit
tk.call("PyAggImagePhoto", photoimage, id(aggimage), colormode, id(bbox_array))
RuntimeError: main thread is not in main loop