Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/335.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 为什么matplotlib只需要在主线程中打印?_Python_Multithreading_Python 2.7_Matplotlib_Plot - Fatal编程技术网

Python 为什么matplotlib只需要在主线程中打印?

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

我正试图绘出一台发电机的输出

以下代码按预期工作(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()

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