2

社内に分散コンピューティング ライブラリがあり、並列コンピューティング ジョブに常に使用しています。プロセスが分割された後、データの読み込みと計算のステップを実行し、「保存」ステップで終了します。通常、これにはデータベース テーブルへのデータの書き込みが含まれます。

しかし、特定のタスクでは、各プロセスの出力をいくつかのデータ プロットを含む .png ファイルにする必要があります。全部で 95 のプロセスがあるので、95 個の .png があります。

「保存」ステップ (各プロセスで実行) の内部には、matplotlib のboxplot関数を使用して箱ひげ図を作成する非常に単純なコードとsavefig、特定のデータに基づいて一意の名前を持つ .png ファイルに書き込むために使用するコードがあります。そのプロセスで使用されます。

ただし、一意の名前にもかかわらず、2 つ以上のデータ セットが同じ出力ファイルに書き込まれたように見える出力が表示されることがあります。

箱ひげ図を作成したり図を保存したりするときに、matplotlib は一時ファイルの保存を使用しますか? その場合、常に同じ一時ファイル名を使用しますか (したがって、上書きの競合が発生します)。を使用してプロセスを実行しstraceましたが、matplotlib からの一時ファイルの書き込みのように見えるものは何も表示されません。

これがスレッドセーフであることを確認するにはどうすればよいですか? 出力.pngの数を大幅に拡大しようとしているため、ファイルの保存を並行して実行したいので、最初にすべてのデータを保存してから、プロット/保存部分をシリアルに実行するというオプションは非常に望ましくありません。

私たちが使用している完全な並列インフラストラクチャを再現することは不可能ですが、以下は、プロット ハンドルを作成するために呼び出される関数と、プロットを保存するために呼び出される関数です。質問のために、スレッド セーフは分散ライブラリとは何の関係もないと仮定する必要があります。これは、このようなスレッド化の問題のないマルチプロセッシング ジョブに何年も使用されてきたコードからのものではないことがわかっています (特に、matplotlib の一時ファイルのように、直接制御しないものには使用されません)。

import pandas
import numpy as np
import matplotlib.pyplot as plt

def plot_category_data(betas, category_name):
    """
    Function to organize beta data by date into vectors and pass to box plot
    code for producing a single chart of multi-period box plots.
    """
    beta_vector_list = []
    yms = np.sort(betas.yearmonth.unique())
    for ym in yms:
        beta_vector_list.append(betas[betas.yearmonth==ym].Beta.values.flatten().tolist())
    ###

    plot_output = plt.boxplot(beta_vector_list)
    axs = plt.gcf().gca()
    axs.set_xticklabels(betas.FactorDate.unique(), rotation=40, horizontalalignment='right')
    axs.set_xlabel("Date")
    axs.set_ylabel("Beta")
    axs.set_title("%s Beta to BMI Global"%(category_name))
    axs.set_ylim((-1.0, 3.0))

    return plot_output
### End plot_category_data

def save(self):
    """
    Make calls to store the plot to the desired output file.
    """
    out_file = self.output_path + "%s.png"%(self.category_name)
    fig = plt.gcf()
    fig.set_figheight(6.5)
    fig.set_figwidth(10)
    fig.savefig(out_file, bbox_inches='tight', dpi=150)
    print "Finished and stored output file %s"%(out_file)
    return None
### End save
4

1 に答える 1

0

2つの関数では、を呼び出していますplt.gcf()。プロットするたびに新しい図を生成し、plt.figure()それを明示的に参照して、問題全体を完全に回避するようにします。

于 2013-01-29T17:05:15.900 に答える