Python,当动画由传入的传感器数据

时间:2017-08-08 21:57:19

标签: python animation matplotlib raspberry-pi

我从一些传感器获取Raspberry Pi的数据。 动画开始后,我还没有办法让它停止动画,然后执行程序中的其余代码。 我试过quit()和animation.event_source.stop()无济于事。我阅读了文档,它看起来像方法animation.FuncAnimation()是一种调用animate()的循环,并且永远不会在我的情况下结束。以下是我的代码的几个版本。版本低于注释掉的行之间没有任何变化。

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之后将print语句放在各个地方,并且代码永远不会超过该点。

任何提示?

1 个答案:

答案 0 :(得分: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()