如何使用Funcanimation用Matplotlib更新和动画多个数字



尝试创建一个读取序列数据并更新多个图形的程序(目前为1行和2个条形图,但可能更多)。

现在使用3个单独的调用funcanimation(),但是事实证明确实很慢,这不是很好,因为我仍然需要在将来添加更多动画数字的选择。

那么,我如何才能使其成为一个更新所有三个(可能更多)数字的单一娱乐场所(或类似的东西)?另外,我该怎么做才能加快速度?

#figure for current
amps = plt.figure(1)
ax1 = plt.subplot(xlim = (0,100), ylim = (0,500))
line, = ax1.plot([],[])
ax1.set_ylabel('Current (A)')
#figure for voltage
volts = plt.figure(2)
ax2 = plt.subplot()
rects1 = ax2.bar(ind1, voltV, width1)
ax2.grid(True)
ax2.set_ylim([0,6])
ax2.set_xlabel('Cell Number')
ax2.set_ylabel('Voltage (V)')
ax2.set_title('Real Time Voltage Data')
ax2.set_xticks(ind1)
#figure for temperature
temp = plt.figure(3)
ax3 = plt.subplot()
rects2 = ax3.bar(ind2, tempC, width2)
ax3.grid(True)
ax3.set_ylim([0,101])
ax3.set_xlabel('Sensor Number')
ax3.set_ylabel('temperature (C)')
ax3.set_title('Real Time Temperature Data')
ax3.set_xticks(ind2)
def updateAmps(frameNum):
    try:
    #error check for bad serial data
        serialString = serialData.readline()
        serialLine = [float(val) for val in serialString.split()]
        print (serialLine)
        if (len(serialLine) == 5):
            voltV[int(serialLine[1])] = serialLine[2]
            tempC[int(serialLine[3])] = serialLine[4]
            currentA.append(serialLine[0])
            if (len(currentA)>100):
                currentA.popleft()
        line.set_data(range(100), currentA)
    except ValueError as e:
    #graphs not updated for bad serial data
        print (e)
    return line,
#function to update real-time voltage data
def updateVolts(frameNum):
    for rects, h in zip(rects1,voltV):
        rects.set_height(h)
    return rects1
#function to update real-time temperature data
def updateTemp(frameNum):
    for rects, h in zip(rects2,tempC):
        rects.set_height(h)
    return rects2

致电Funcanimation:

anim1 = animation.FuncAnimation(amps, updateAmps,
                                interval = 20, blit = True)
anim2 = animation.FuncAnimation(volts, updateVolts, interval = 25, blit = True)
anim3 = animation.FuncAnimation(temp, updateTemp, interval = 30, blit = True)

echoing @quentional ofbeernest的评论,显而易见的解决方案是使用3个子图,只有一个FuncAnimation()调用。您只需要确保您的回调功能返回每次迭代时要更新的所有艺术家的列表。

一个缺点是,在所有3个子图中,更新将与一个相同的间隔发生(与示例中的不同时间相反)。您可以通过使用计算调用该函数多少次的全局变量来解决此问题,并且只经常进行某些图。

#figure 
fig = plt.figure(1)
# subplot for current
ax1 = fig.add_subplot(131, xlim = (0,100), ylim = (0,500))
line, = ax1.plot([],[])
ax1.set_ylabel('Current (A)')
#subplot for voltage
ax2 = fig.add_subplot(132)
rects1 = ax2.bar(ind1, voltV, width1)
ax2.grid(True)
ax2.set_ylim([0,6])
ax2.set_xlabel('Cell Number')
ax2.set_ylabel('Voltage (V)')
ax2.set_title('Real Time Voltage Data')
ax2.set_xticks(ind1)
#subplot for temperature
ax3 = fig.add_subplot(133)
rects2 = ax3.bar(ind2, tempC, width2)
ax3.grid(True)
ax3.set_ylim([0,101])
ax3.set_xlabel('Sensor Number')
ax3.set_ylabel('temperature (C)')
ax3.set_title('Real Time Temperature Data')
ax3.set_xticks(ind2)
def updateAmps(frameNum):
    try:
    #error check for bad serial data
        serialString = serialData.readline()
        serialLine = [float(val) for val in serialString.split()]
        print (serialLine)
        if (len(serialLine) == 5):
            voltV[int(serialLine[1])] = serialLine[2]
            tempC[int(serialLine[3])] = serialLine[4]
            currentA.append(serialLine[0])
            if (len(currentA)>100):
                currentA.popleft()
        line.set_data(range(100), currentA)
    except ValueError as e:
    #graphs not updated for bad serial data
        print (e)
    return line,
#function to update real-time voltage data
def updateVolts(frameNum):
    for rects, h in zip(rects1,voltV):
        rects.set_height(h)
    return rects1
#function to update real-time temperature data
def updateTemp(frameNum):
    for rects, h in zip(rects2,tempC):
        rects.set_height(h)
    return rects2
def updateALL(frameNum):
    a = updateAmps(frameNum)
    b = updateVolts(frameNum)
    c = updateTemp(frameNum)
    return a+b+c
animALL = animation.FuncAnimation(fig, updateALL,
                                interval = 20, blit = True)

最新更新