Python matplotlib在简单线程中打印冻结
一直在玩Python的绘图库,遇到了matplotlib,它似乎已经经过了战斗测试和验证。然而,我在线程中创建一个简单的绘图时遇到了一个问题 在下面的示例中,Dummyclassplotme方法在一个线程中连续运行两次,但在第二次迭代中被卡住/冻结。 最有可能的是一些明显的和线程本身相关的东西,但到目前为止我没有发现它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):
导入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)