1. ホーム
  2. python

[解決済み] Matplotlibでノンブロッキングにプロットする

2022-04-22 12:21:13

質問

ここ数日、Numpyとmatplotlibで遊んでいます。matplotlibが実行をブロックすることなく関数をプロットしようとしていることに問題があります。私はすでにSOで同様の質問をする多くのスレッドがあることを知っていますし、私はかなり多くのことをググりましたが、これを動作させることはできませんでした。

何人かの人が提案するようにshow(block=False)を使ってみましたが、得られるのはフリーズしたウィンドウだけです。単にshow()を呼び出すと、結果は適切にプロットされますが、ウィンドウが閉じられるまで実行がブロックされます。私が読んだ他のスレッドから、show(block=False)が機能するかどうかは、バックエンドに依存すると思われます。これは正しいのでしょうか?私のバックエンドはQt4Aggです。私のコードを見て、何か間違っていることがあれば教えてください。以下が私のコードです。助けてくれてありがとう。

from math import *
from matplotlib import pyplot as plt
print(plt.get_backend())



def main():
    x = range(-50, 51, 1)
    for pow in range(1,5):   # plot x^1, x^2, ..., x^4

        y = [Xi**pow for Xi in x]
        print(y)

        plt.plot(x, y)
        plt.draw()
        #plt.show()             #this plots correctly, but blocks execution.
        plt.show(block=False)   #this creates an empty frozen window.
        _ = raw_input("Press [enter] to continue.")


if __name__ == '__main__':
    main()

PS. 言い忘れましたが、新しいウィンドウを作るのではなく、何かをプロットするたびに既存のウィンドウを更新したいのです。

解決方法は?

長い時間をかけて解決策を探し、見つけたのが この答え .

どうやら、あなた(と私)が望むものを手に入れるには、以下の組み合わせが必要なようです。 plt.ion() , plt.show() (ただし block=False ) そして、最も重要なのは plt.pause(.001) (または好きな時間)。その ポーズ が必要なのは、メインコードがスリープしている間に、描画を含むGUIイベントが発生するためです。これはスリープしているスレッドから時間を拾って実装されている可能性があるので、IDEがそれを邪魔しているのかもしれませんね。

python 3.5で動作する実装を紹介します。

import numpy as np
from matplotlib import pyplot as plt

def main():
    plt.axis([-50,50,0,10000])
    plt.ion()
    plt.show()

    x = np.arange(-50, 51)
    for pow in range(1,5):   # plot x^1, x^2, ..., x^4
        y = [Xi**pow for Xi in x]
        plt.plot(x, y)
        plt.draw()
        plt.pause(0.001)
        input("Press [enter] to continue.")

if __name__ == '__main__':
    main()