1

バックグラウンド:

3D データの 2D 断面を表示するプログラムに取り組んでいます。データは、x、y、z1、z2、z3 などの形式の単純なテキスト csv ファイルに保存されます。始点と終点を取得し、データセット (〜 110,000 行) をフリックして、これらの間に点の線を作成します。 2 つの場所に配置し、それらを配列にダンプします。これは問題なく動作し、かなり高速です (約 0.3 秒かかります)。この線を表示するために、matplotlib 積み上げ棒グラフを作成しました。ただし、プログラムの合計実行時間は約 5.5 秒です。その大部分 (3 秒相当) を以下のコードに絞り込みました。
'values' は、x、y、z の値と先頭の識別子を含む配列であり、コードのこの部分では使用されません。最初の plt.bar はバー セクションをプロットし、2 番目は -2000 の任意のフロアを作成するために使用されます。連続的に見えるセクションを生成するために、各バー間の間隔をゼロにしています。

    import matplotlib.pyplot as plt

    for values in crossSection:
        prevNum = None
        layerColour = None
        if values != None:
            for i in range(3, len(values)):
                if values[i] != 'n':
                    num = float(values[i].strip())
                    
                    if prevNum != None:
                        plt.bar(spacing, prevNum-num, width=interval, \
                                bottom=num, color=layerColour, \
                                edgecolor=None, linewidth=0)
                        
                    prevNum = num
                    
                    layerColour = layerParams[i].strip()
                    
            if prevNum != None:        
                plt.bar(spacing, prevNum+2000, width=interval, bottom=-2000, \
                                    color=layerColour, linewidth=0)
        
        spacing += interval

これを行うためのより効率的な方法があると確信していますが、私は Matplotlib を初めて使用し、その機能にまだ慣れていません。コードでの時間のその他の主な用途は次のとおりです。

plt.savefig('output.png')

これには約 1 秒かかりますが、これでファイルが保存されることが予想されるため、何もできません。

質問:

plt.bar()より良い、または別の Matplotlib 関数を使用して、同じ出力 (積み上げ棒グラフまたはそのようなもの) を生成するより高速な方法はありますか?

編集: 元の投稿で、Python 3.2.3 と Matplotlib 1.2.0 を使用していることを忘れていました。

4

2 に答える 2

2

誰かが同じ問題に遭遇した場合に備えて、これをここに残しておきます...
を使用する場合とまったく同じではありませんがbar()、十分に大きなデータセット (使用bar()するのに数秒かかるほど大きい) では、結果はstackplot(). tcaswell で指定されたメソッドを使用してデータをレイヤーに並べ替え、それをstackplot()チャートにフィードすると、3 秒ではなく 0.2 秒で作成されます。

編集

データをレイヤーに変換するために tcaswell が提供するコード:

accum_values = []
for values in crosssection:
    accum_values.append([float(v.strip()) for v iv values[3:]])
accum_values = np.vstack(accum_values).T 
layer_params = [l.strip() for l in layerParams]
bottom = numpy.zeros(accum_values[0].shape)
于 2013-01-11T00:26:48.637 に答える
1

各バーを描画しているように見えます。シーケンスを渡すことができますbar(この を参照してください)

私は次のように思います:

accum_values = []
for values in crosssection:
    accum_values.append([float(v.strip()) for v iv values[3:]])


accum_values = np.vstack(accum_values).T 
layer_params = [l.strip() for l in layerParams]
bottom = numpy.zeros(accum_values[0].shape)

ax = plt.gca()
spacing = interval*numpy.arange(len(accum_values[0]))
for data,color is zip(accum_values,layer_params):
    ax.bar(spacing,data,bottom=bottom,color=color,linewidth=0,width=interval)
    bottom += data

高速になります(バーを呼び出すたびに1つ作成されるためBarContainer、問題の原因は、レイヤーごとに1つではなく、バーごとに1つ作成していたためだと思います)。

上が下にあるバーで何をしているのかよくわからないので、それを実装しようとしなかったので、これを少し調整する必要があります。

于 2013-01-10T04:18:04.910 に答える