22

私がやろうとしているのは、スクリプトに何かを計算させ、プロットを準備し、既に取得した結果を pylab.figure として表示することです - Python 2 (特に python 2.7) で安定した matplotlib (1.1.1) を使用します。

Python 3 (matplotlib git build ... バージョン 1.2.x を使用した Python 3.2.3) では、これは正常に機能します。簡単な例として (time.sleep() による長い計算をシミュレートする) 考えてみましょう

import pylab
import time
import random

dat=[0,1]
pylab.plot(dat)
pylab.ion()
pylab.draw()    
for i in range (18):
    dat.append(random.uniform(0,1))
    pylab.plot(dat)
    pylab.draw()
    time.sleep(1)

Python 2 (バージョン 2.7.3 with matplotlib 1.1.1) では、コードはエラーなしで正常に実行されますが、図は表示されません。python2 インタープリターでの試行錯誤の結果、pylab.draw() を pylab.show(); に置き換えることが提案されたようです。これを 1 回実行するだけで明らかに十分です (プロットに変更や追加を行うたびに draw を呼び出すのとは異なります)。したがって:

import pylab
import time
import random

dat=[0,1]
pylab.plot(dat)
pylab.ion()
pylab.show()    
for i in range (18):
    dat.append(random.uniform(0,1))
    pylab.plot(dat)
    #pylab.draw()
    time.sleep(1)

ただし、これも機能しません。繰り返しますが、きれいに実行されますが、図は表示されません。ユーザーの入力を待っているときにのみそうするようです。これがなぜなのかはわかりませんが、 raw_input() がループに追加されると、プロットが最終的に表示されます

import pylab
import time
import random

dat=[0,1]
pylab.plot(dat)
pylab.ion()
pylab.show()    
for i in range (18):
    dat.append(random.uniform(0,1))
    pylab.plot(dat)
    #pylab.draw()
    time.sleep(1)
    raw_input()

これにより、スクリプトはもちろん、プロットを表示している間、ユーザーの入力を待ち、ユーザーが Enter キーを押すまでデータの計算を続行しません。もちろん、これは意図したものではありません。

これは、異なるバージョンの matplotlib (1.1.1 および 1.2.x) または異なる python バージョン (2.7.3 および 3.2.3) が原因である可能性があります。

上記のスクリプト(最初のスクリプト)がpython 3、matplotlib 1.2.xで行うことを安定した(1.1.1)matplotlibでpython 2で達成する方法はありますか: - データの計算(上記の例では時間がかかります)ループまたは反復関数で time.sleep()) によってシミュレートされ、- (まだ計算中に) 以前の反復で既に計算されたものを表示し、ユーザーが計算を続行するために Enter キーを押し続ける必要がありません。

ありがとう; 助けていただければ幸いです...

4

2 に答える 2

23

このpause関数で、GUI フレームワークに画面を再描画する機会を与える必要があります。

import pylab
import time
import random
import matplotlib.pyplot as plt

dat=[0,1]
fig = plt.figure()
ax = fig.add_subplot(111)
Ln, = ax.plot(dat)
ax.set_xlim([0,20])
plt.ion()
plt.show()    
for i in range (18):
    dat.append(random.uniform(0,1))
    Ln.set_ydata(dat)
    Ln.set_xdata(range(len(dat)))
    plt.pause(1)

    print 'done with loop'

Line2Dパススルーごとに新しいオブジェクトを作成する必要はありません。既存のデータを更新するだけで済みます。

ドキュメンテーション:

pause(interval)
    Pause for *interval* seconds.

    If there is an active figure it will be updated and displayed,
    and the gui event loop will run during the pause.

    If there is no active figure, or if a non-interactive backend
    is in use, this executes time.sleep(interval).

    This can be used for crude animation. For more complex
    animation, see :mod:`matplotlib.animation`.

    This function is experimental; its behavior may be changed
    or extended in a future release.

本当に過剰な方法は、matplotlib.animateモジュールを使用することです。反対に、必要に応じてデータを保存するための優れた方法を提供します(Python-1秒プロット連続プレゼンテーションへの私の回答から抜粋)。

APIチュートリアル

于 2012-10-10T18:48:11.587 に答える
2

@tcaswellが提案したように、一部のバックエンド(私の経験では「Qt4Agg」)にはpause関数が必要です。

他のバックエンド (私の経験では "TkAgg") はdraw()pause. したがって、別の解決策は、たとえば、バックエンドを切り替えることmatplotlib.use('TkAgg')です。

于 2015-03-20T02:05:59.133 に答える