Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.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_Matplotlib_Plot_Freeze - Fatal编程技术网

Python matplotlib在简单线程中打印冻结

Python matplotlib在简单线程中打印冻结,python,multithreading,matplotlib,plot,freeze,Python,Multithreading,Matplotlib,Plot,Freeze,一直在玩Python的绘图库,遇到了matplotlib,它似乎已经经过了战斗测试和验证。然而,我在线程中创建一个简单的绘图时遇到了一个问题 在下面的示例中,Dummyclassplotme方法在一个线程中连续运行两次,但在第二次迭代中被卡住/冻结。 最有可能的是一些明显的和线程本身相关的东西,但到目前为止我没有发现它 导入matplotlib.pyplot作为plt 来自numpy import arange,sin,pi 导入线程 类Dummy(): def plotme(自身,迭代=1):

一直在玩Python的绘图库,遇到了matplotlib,它似乎已经经过了战斗测试和验证。然而,我在线程中创建一个简单的绘图时遇到了一个问题

在下面的示例中,Dummyclassplotme方法在一个线程中连续运行两次,但在第二次迭代中被卡住/冻结。 最有可能的是一些明显的和线程本身相关的东西,但到目前为止我没有发现它

导入matplotlib.pyplot作为plt
来自numpy import arange,sin,pi
导入线程
类Dummy():
def plotme(自身,迭代=1):
打印“%ix打印…”迭代,
t=arange(0.0,2.0,0.01)
s=sin(2*pi*t)
平面图(t,s)
plt.xlabel(“时间”)
plt.ylabel('电压(mV)')
plt.title('尽可能简单,伙计们')
#savefig(“test.png”)#与此无关
plt.close()
def threadme(自身,迭代=1):
thread\u plot=threading.thread(target=self.plotme,
args=(迭代,)
线程\u plot.start()
线程_plot.join()
dummy=dummy()
dummy.threadme(1)
虚拟线程(2)

首先,请注意
pyplot
-接口不是线程安全的

然后:使用“Agg”-后端以非交互方式创建多个图像

一个工作示例(由于线程可能出现问题)是:

线程安全版本如下所示:

import matplotlib
matplotlib.use("Agg")
import matplotlib.pyplot as plt
from numpy import arange, sin, pi
import threading

class Dummy():

    def plotme(self, iteration = 1):

        print "%ix plotting... " % iteration,
        t = arange(0.0, 2.0, 0.01)
        s = sin(2*pi*t)

        fig, ax = plt.subplots()
        ax.plot(t, s)
        ax.set_xlabel('time (s)')
        ax.set_ylabel('voltage (mV)')
        ax.set_title('About as simple as it gets, folks (%i)' % iteration)
        fig.savefig("19110942_%i_test.png" % iteration)

    def threadme(self, iteration = 1):

        thread_plot = threading.Thread(target=self.plotme,
                                      args=(iteration,))
        thread_plot.start()
        thread_plot.join()

dummy = Dummy()
dummy.threadme(1)
dummy.threadme(2)

您知道matplotlib.pyplot中的命令不是线程安全的吗?您应该使用OOÜP方法,比如创建一个图形、一个Axis对象,然后调用这个Axis对象上的方法,例如,
ax.plot(…)
谢谢@Thorsten Kranz,就是这样。我应该对pyplot的“线程安全性”进行适当的调查(注:我在过去几天一直在研究这个问题,我可以自信地说,上面的第二个版本并不比第一个版本更“线程安全”,如果没有调用
matplotlib.use('Agg')
,它们都会很高兴地挂起后续的线程运行。关键是使用非交互模式,然后两者都会在一个线程中愉快地运行很多次而不会出错。
import matplotlib
matplotlib.use("Agg")
import matplotlib.pyplot as plt
from numpy import arange, sin, pi
import threading

class Dummy():

    def plotme(self, iteration = 1):

        print "%ix plotting... " % iteration,
        t = arange(0.0, 2.0, 0.01)
        s = sin(2*pi*t)

        fig, ax = plt.subplots()
        ax.plot(t, s)
        ax.set_xlabel('time (s)')
        ax.set_ylabel('voltage (mV)')
        ax.set_title('About as simple as it gets, folks (%i)' % iteration)
        fig.savefig("19110942_%i_test.png" % iteration)

    def threadme(self, iteration = 1):

        thread_plot = threading.Thread(target=self.plotme,
                                      args=(iteration,))
        thread_plot.start()
        thread_plot.join()

dummy = Dummy()
dummy.threadme(1)
dummy.threadme(2)