2017-08-08 66 views
1

我正從某些傳感器獲取樹莓派的數據。 一旦動畫開始,我還沒有找到一種方法讓它停止動畫,然後執行程序中的其餘代碼。 我試過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,然後將代碼的其餘部分將執行,程序就結束了,但動畫繼續工作,直到我的鍵盤中斷多次,而其餘代碼(在除外)從未運行。我也曾嘗試...

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() 

我也試圖把打印語句在不同的地方ANI分配行後plt.show後,代碼永遠不會越過這一點。

任何提示?

回答

1

plt.show()後面的代碼將僅在所顯示的窗口關閉後才執行。此時,您還沒有pyplot中的數字可以使用plt.savefig。然而,你可能很好地創建了一個新的情節,就像你已經在代碼中做的那樣,一旦你關閉了matplotlib窗口,第二個版本的代碼應該運行良好。

#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

嘿感謝張貼。我試過你的第二塊代碼,並且動畫不會顯示,除非我在分配了哪個ani之後放置了一行plt.show()。當我放入plt節目時,我遇到了和以前一樣的問題。代碼是否可以在您的計算機上運行?我來自Raspbian的pi終端(linux操作系統)。 –

+1

是的兩個代碼都是按原樣運行的(因此我模擬了MCP3008的一部分,這樣代碼就可以被複制和粘貼)。很明顯,如果'plt.show'不是最後的結果,而是之前的某個地方,則不會發生所需的保存。我不知道爲什麼它不適合你。第一個版本至少按預期運行? – ImportanceOfBeingErnest

+0

得到它的工作!謝謝!我需要plt.show(),否則會關閉程序。非常感謝! –