4

Python のプロット ライブラリで遊んでいて、matplotlib に出くわしました。ただし、スレッドで単純なプロットを作成しているときに問題が発生しました。

次の例では、ダミークラスのplotmeメソッドがスレッドで 2 回連続して実行されますが、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)
4

1 に答える 1

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)
于 2013-10-01T08:16:48.477 に答える