我试图用FuncAnimation
中的matplotlib
在两个子图中绘制实时数据。最终目标是绘制来自arduino的实时传感器数据。
在没有图形卡运行debian 9的5年旧计算机上,绘制的随机游动以200 fps的速度显示。每个子图显示4个随机游动。
问题是 y轴未相应更新。图片中的性能统计数据显示ax1.y_lim
位于[-108; 94]
中,但是ax1
中的y轴或多或少地位于[-5;2]
中。
#!/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值,则帧速率会大幅下降。