2017-08-08 7 views
1

いくつかのセンサーからRaspberry Piにデータを取得しています。 アニメーションが開始されると、アニメーションを停止してプログラムの残りのコードを実行する方法が見つかりませんでした。 私はquit()とanimation.event_source.stop()を無駄にしようとしました。私はドキュメントを読んで、メソッドanimation.FuncAnimation()はanimate()を呼び出すループのようなもので、私の場合は終了しません。以下に私のコードのいくつかのバージョンを示します。コメントアウトされた行の下のバージョンは変更されません。 (Python、matplotlibを終了するFuncAmination()アニメーションが受信センサーデータによって供給される場合

from gpiozero import MCP3008 
from timeit import default_timer 
import time 
import matplotlib.pyplot as plt 
import matplotlib.animation as animation 
from matplotlib import style 

# This is specific to the ADC I am using for my sensor 
ch2 = MCP3008(2) 
vals = [] 
timer = [] 
fig = plt.figure() 
ax1 = fig.add_subplot(1,1,1) 

#this is the fuction used as a parameter for the animation.FuncAnimation 
def animate(i): 
    timer.append(default_timer()) 
    vals.append(ch2.value) 
    ax1.clear() 
    ax1.plot(timer,vals) 
#______________________________________ 
try: 
    ani = animation.FuncAnimation(fig, animate, interval = 50) 
    plt.show() 

except KeyboardInterrupt: 
    plt.close("all") 
    #The plot created below is for saving the final set of collected data 
    plt.plot(timer,vals) 
    plt.xlabel("Time(s)") 
    plt.ylabel("V") 
    plt.savefig('/home/pi/programs/pics/plot.jpg') 
    plt.close('all') 
    quit() 

アイデアは、あなたが、コントロールCを押すだろうし、コードの残りの部分が実行さだろうとプログラムが終わるだろうということでしたが、私のキーボードは複数回を中断するまで、アニメーションは動作を続け、そして残りのコード例外を除いて)実行されません。また、私はまた、ANIが割り当てられている行の後plt.show後に様々な場所でprint文を入れてみました、そしてコードは、その点を過ぎて取得することはありません...

from gpiozero import MCP3008 
from timeit import default_timer 
import time 
import matplotlib.pyplot as plt 
import matplotlib.animation as animation 
from matplotlib import style 

# This is specific to the ADC I am using for my sensor 
ch2 = MCP3008(2) 
vals = [] 
timer = [] 
fig = plt.figure() 
ax1 = fig.add_subplot(1,1,1) 

#this is the fuction used as a parameter for the animation.FuncAnimation 
def animate(i): 
    timer.append(default_timer()) 
    vals.append(ch2.value) 
    ax1.clear() 
    ax1.plot(timer,vals) 
#______________________________________ 
ani = animation.FuncAnimation(fig, animate, interval = 50) 
plt.show() 
commmand = input('Type q and press enter to quit') 

if commmand == 'q': 
    plt.close("all") 
    #The plot created below is for saving the final set of collected data 
    plt.plot(timer,vals) 
    plt.xlabel("Time(s)") 
    plt.ylabel("V") 
    plt.savefig('/home/pi/programs/pics/plot.jpg') 
    plt.close('all') 
    quit() 

を試してみました。

ヒント?

答えて

1

plt.show()の後のコードは、表示されたウィンドウが閉じられると実行されます。その時点で、あなたはplt.savefigを使用するためにpyplotで利用可能な数字を持っていません。しかし、コード内ですでにやっているように、新しいプロットを作成して、matplotlibウィンドウを閉じると2番目のバージョンのコードをうまく実行する必要があります。

#from gpiozero import MCP3008 # not available here 
from timeit import default_timer 
import matplotlib.pyplot as plt 
import matplotlib.animation as animation 

# emulate sensor 
class MCP3008(): 
    def __init__(self, r): 
     self.x = 0.5 
     self.r = r 
    def value(self): 
     self.x = self.r*self.x*(1.-self.x) 
     return self.x 
ch2 = MCP3008(3.62) 
vals = [] 
timer = [] 
fig = plt.figure() 
ax1 = fig.add_subplot(1,1,1) 

#this is the fuction used as a parameter for the animation.FuncAnimation 
def animate(i): 
    timer.append(default_timer()) 
    vals.append(ch2.value()) 
    ax1.clear() 
    ax1.plot(timer,vals, marker=".", ls="") 

ani = animation.FuncAnimation(fig, animate, interval = 50) 
plt.show() 

plt.close("all") 
#The plot created below is for saving the final set of collected data 
plt.plot(timer,vals) 
plt.xlabel("Time(s)") 
plt.ylabel("V") 
plt.savefig('plot.jpg') 
plt.close('all') 

プロットを開いたままにして、キーを押すとプロットを保存する場合は、次のオプションがあります。 qキーが押された状態で実際のプロットを保存します。 (また、軸は反復ごとにクリアされませんが、アプローチを示すためにラインデータのみが更新されます)。

#from gpiozero import MCP3008 # not available here 
from timeit import default_timer 
import matplotlib.pyplot as plt 
import matplotlib.animation as animation 

# emulate sensor 
class MCP3008(): 
    def __init__(self, r): 
     self.x = 0.5 
     self.r = r 
    def value(self): 
     self.x = self.r*self.x*(1.-self.x) 
     return self.x 
ch2 = MCP3008(3.62) 
vals = [] 
timer = [] 
fig = plt.figure() 
ax1 = fig.add_subplot(1,1,1) 
line, = ax1.plot([],[], marker=".", ls="") 
ax1.set_xlabel("Time(s)") 
ax1.set_ylabel("V") 

#this is the fuction used as a parameter for the animation.FuncAnimation 
def animate(i): 
    timer.append(default_timer()) 
    vals.append(ch2.value()) 
    line.set_data(timer,vals) 
    ax1.relim() 
    ax1.autoscale_view() 

ani = animation.FuncAnimation(fig, animate, interval = 50) 

def press(event): 
    if event.key == 'q': 
     ani.event_source.stop() 
     fig.savefig("plot.png") 
     print("Plot saved") 

cid = fig.canvas.mpl_connect('key_press_event', press) 

plt.show() 
+0

投稿いただきありがとうございます。私はコードの2番目のブロックを試してアニメーションが表示されない限り、アニメーションが割り当てられた場所の後にplt.show()という行を置かない限り表示されません。私がpltショーに参加したとき、以前と同じ問題に遭遇しました。コードはあなたのコンピュータ上で動作しますか?私はpi(Linux OS)のRaspbianのターミナルから来ています。 –

+1

はい、両方のコードがそのまま実行されます(このため、MCP3008の部分をエミュレートして、コードをコピーして貼り付けることができます)。 'plt.show'が最後ではなく前の場所であれば、必要な保存は行われないことは明らかです。私はなぜそれがあなたのために働かないかわからない。最初のバージョンは少なくとも期待どおりに動作しますか? – ImportanceOfBeingErnest

+0

うまくいきました!ありがとう!私は最後にplt.show()が必要だったのですが、プログラムを切断してしまいました。本当にありがとう! –

関連する問題