2013-10-01 5 views
4

파이썬 용 플로팅 라이브러리를 사용하고 있으며 이미 전투 테스트를 거쳐 입증 된 matplotlib를 발견했습니다. 그러나 스레드에서 간단한 줄거리를 만드는 동안 문제를 발견했습니다. 예 울부 짖는 소리에 matplotlib 간단한 스레드에서 멈추는 플로팅

, 더미 클래스 방법은 두 번 연속 스레드에서 실행 plotme하지만 2 차 반복에 갇혀/정지를 가져옵니다. 스레딩 자체와 관련하여 분명하고 관련이있는 항목이 많지만 지금까지는 그 문제점을 발견하지 못했습니다.

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) 
     plt.plot(t, s) 
     plt.xlabel('time (s)') 
     plt.ylabel('voltage (mV)') 
     plt.title('About as simple as it gets, folks') 
     #savefig("test.png") # irrelevant here 
     plt.close() 

    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) 
+1

당신이 알고 matplotlib.pyplot의 명령 것을 있습니까 hread-safe가 아닌가? 당신은 그림, 축 객체를 생성 한 다음이 축 객체에 대한 메소드를 호출하는 것과 같은 OOUP 접근법을 사용해야합니다. 'ax.plot (...)' –

답변

5

우선 pyplot -interface는 스레드로부터 안전하지 않습니다.

다음 : 여러 이미지를 비 대화식으로 만들려면 "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) 
     plt.plot(t, s) 
     plt.xlabel('time (s)') 
     plt.ylabel('voltage (mV)') 
     plt.title('About as simple as it gets, folks') 
     plt.savefig("19110942_%i_test.png" % iteration) # irrelevant here 
     plt.clf() 

    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) 

스레드 안전 버전은 다음과 같을 것이다 :

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) 
+0

고마워요. @Thorsten Kranz 그게 전부입니다. 나는 pyplot "thread-safeness"에 대해 제대로 조사 했어야했다. :) –

+1

참고 : 지난 며칠 동안 이걸 가지고 놀았으며 위의 두 번째 버전이 더 이상 '스레드 안전'이 아니라고 확신 할 수 있다고 확신 할 수있다. 'matplotlib.use ('Agg')'가 호출되지 않으면 **, 둘 다 연속적으로 스레드 된 실행에 행복하게 매달릴 것이다 **. 키는 비대화 형 모드를 사용하며, 둘 다 행복없이 여러 번 여러 번 스레드에서 실행됩니다. – SiHa

+2

대화 형 ** 플로팅에 대한 스레드 안전 옵션이 있습니까? – SPRajagopal

관련 문제