首页 > 解决方案 > Matplotlib如何在实时动画中沿数据移动轴

问题描述

我正在尝试绘制在运行时生成的数据。为了做到这一点,我正在使用matplotlib.animation.FuncAnimation.

虽然数据正确显示,但轴值不会根据正在显示的值进行更新:

图形动画

x 轴显示从 0 到 10 的值,尽管我在update_line函数的每次迭代中更新它们(参见下面的代码)。

DataSource包含数据向量并在运行时附加值,还返回正在返回的值的索引:

import numpy as np

class DataSource:
    data = []
    display = 10

    # Append one random number and return last 10 values
    def getData(self):
        self.data.append(np.random.rand(1)[0])
        if(len(self.data) <= self.display):
            return self.data
        else:
            return self.data[-self.display:]

    # Return the index of the last 10 values
    def getIndexVector(self):
        if(len(self.data) <= self.display):
            return list(range(len(self.data)))

        else:
            return list(range(len(self.data)))[-self.display:]

我已经从matplotlib文档中获得了这个plot_animation功能。

import numpy as np
import matplotlib.pyplot as plt
import matplotlib.animation as animation
from datasource import DataSource


def update_line(num, source, line):
    data = source.getData()
    indexs = source.getIndexVector()
    if indexs[0] != 0:
        plt.xlim(indexs[0], indexs[-1])
        dim=np.arange(indexs[0],indexs[-1],1)
        plt.xticks(dim)
    line.set_data(indexs,data)
    return line,

def plot_animation():
    fig1 = plt.figure()
    source = DataSource()

    l, = plt.plot([], [], 'r-')

    plt.xlim(0, 10)
    plt.ylim(0, 1)
    plt.xlabel('x')
    plt.title('test')
    line_ani = animation.FuncAnimation(fig1, update_line, fargs=(source, l),
                                    interval=150, blit=True)

    # To save the animation, use the command: line_ani.save('lines.mp4')


    plt.show()

if __name__ == "__main__":
    plot_animation()

如何在动画的每次迭代中更新 x 轴值?

(如果您发现任何错误,我感谢改进代码的建议,即使它们可能与问题无关)。

标签: pythonmatplotlibmatplotlib-animation

解决方案


这是一个简单的案例,说明如何实现这一点。

import matplotlib.pyplot as plt
import matplotlib.animation as animation
import numpy as np
%matplotlib notebook

#data generator
data = np.random.random((100,))

#setup figure
fig = plt.figure(figsize=(5,4))
ax = fig.add_subplot(1,1,1)

#rolling window size
repeat_length = 25

ax.set_xlim([0,repeat_length])
ax.set_ylim([-2,2])


#set figure to be modified
im, = ax.plot([], [])

def func(n):
    im.set_xdata(np.arange(n))
    im.set_ydata(data[0:n])
    if n>repeat_length:
        lim = ax.set_xlim(n-repeat_length, n)
    else:
        lim = ax.set_xlim(0,repeat_length)
    return im

ani = animation.FuncAnimation(fig, func, frames=data.shape[0], interval=30, blit=False)

plt.show()

#ani.save('animation.gif',writer='pillow', fps=30)

在此处输入图像描述


推荐阅读