实时绘制时,matplotlib FuncAnimation不更新轴

时间:2018-12-23 10:03:43

标签: python matplotlib plot

我试图用FuncAnimation中的matplotlib在两个子图中绘制实时数据。最终目标是绘制来自arduino的实时传感器数据。

在没有图形卡运行debian 9的5年旧计算机上,绘制的随机游动以200 fps的速度显示。每个子图显示4个随机游动。 enter image description here

问题是 y轴未相应更新。图片中的性能统计数据显示ax1.y_lim位于[-108; 94]中,但是ax1中的y轴或多或少地位于[-5;2]中。

这个想法来自https://learn.sparkfun.com/tutorials/graph-sensor-data-with-python-and-matplotlib/update-a-graph-in-real-time),程序是:

#!/usr/bin/ipython3 -i

import matplotlib.pyplot as plt
import matplotlib.animation as animation
import numpy as np
import time

class RealTimePlot:
    def __init__(self, fig, bufsize=100, data_rows=8):    
        self.fig = fig
        self.bufsize = bufsize
        self.data_rows = data_rows

        self._init_plot()
        self._init_data()
        self._init_plot2()

        self.fps_start = time.time()
        self.fps_counter, self.fps_print = (0, 100)


    def _init_plot(self):
        plt.ion()
        self.ax1 = self.fig.add_subplot(2, 1, 1)
        self.ax1.set_xlim(0, self.bufsize)
        self.ax2 = self.fig.add_subplot(2, 1, 2)
        self.ax2.set_xlim(0, self.bufsize)


    def _init_data(self):
        self.y = np.zeros((self.data_rows, self.bufsize))
        self.x = list(range(self.bufsize))
        self.data_labels = list(map(chr, range(ord('A'), ord('A') + self.data_rows)))


    def _init_plot2(self):
        self.artists = []
        self.ind_sub1 = range(self.data_rows // 2)
        self.ind_sub2 = range(self.data_rows // 2, self.data_rows)
        for i in self.ind_sub1:
            line, = self.ax1.plot(self.x, self.y[i,:], label=self.data_labels[i])
            self.artists.append(line)
        for i in self.ind_sub2:
            line, = self.ax2.plot(self.x, self.y[i,:], label=self.data_labels[i])
            self.artists.append(line)
        self.ax1.legend()
        self.ax2.legend()
        self.fig.tight_layout()


    def read_data(self):
        new_data = np.random.rand(self.data_rows) * 10 - 5
        ret = self.y[:,-1] + new_data
        return ret.reshape(-1,1)


    def animate(self, i):
        # add new data
        new_data = self.read_data().reshape((self.y.shape[0], 1))
        self.y = np.append(self.y, new_data, axis=1)[:, -self.y.shape[1]:]

        # update plot data
        self.ax1_min, self.ax1_max = (np.min(self.y[self.ind_sub1,:]), np.max(self.y[self.ind_sub1,:]))
        self.ax1.set_ylim(self.ax1_min, self.ax1_max)
        self.ax2_min, self.ax2_max = (np.min(self.y[self.ind_sub2,:]), np.max(self.y[self.ind_sub2,:]))
        self.ax2.set_ylim(self.ax2_min, self.ax2_max)
        for nr, line in enumerate(self.artists):
            line.set_ydata(self.y[nr,:])

        # performance stats
        if self.fps_counter == self.fps_print:
            fps = self.fps_counter // (time.time() - self.fps_start)
            print('FPS:', fps, 'Ax1Min', int(self.ax1_min), 'Ax1Max', int(self.ax1_max),
                    'Ax2Min', int(self.ax2_min), 'Ax2Max', int(self.ax2_max))
            self.fps_counter = 0
            self.fps_start = time.time()
        else:
            self.fps_counter += 1

        return self.artists



fig = plt.figure(figsize=(16,6))
a = RealTimePlot(fig, bufsize=100, data_rows=8)
ani = animation.FuncAnimation(fig, a.animate, interval=0, blit=True)
plt.show()

如何在不损失很多帧率的情况下更改animate函数?

顺便说一句,如果在绘图创建中使用更大的figsize值,则帧速率会大幅下降。

0 个答案:

没有答案