如何对 matplotlib 中的二维数组数据使用 line.set_data ?

lmm*_*mms 2 python numpy matplotlib matplotlib-animation

我正在尝试在 matplotlib 中同时为多行设置动画。为此,我遵循 matplotlib.animation 文档中的教程:

https://matplotlib.org/stable/api/animation_api.html

本教程的想法是创建一条线ln, = plt.plot([], [])并更新该线的数据ln.set_data以生成动画。虽然当线数据是 n 个数据点的一维数组 (shape = (n,)) 时,这一切都工作正常,但当线数据是 n 个数据点的 2 维数组 (shape = (n,k)) 时,我遇到了麻烦要绘制的 k 条线。

更准确地说,plt.plot接受数组作为输入,每列对应于要绘制的新线。下面是一个简单的示例,通过一次plt.plot调用绘制了 3 条线:

import matplotlib.pyplot as plt
import numpy as np


x = np.linspace(0, 2 * np.pi, 100).reshape(-1, 1)
x = np.concatenate([x] * 3, axis=1)

# generate 3 curves
y = np.copy(x)
y[:, 0] = np.cos(y[:, 0])
y[:, 1] = np.sin(y[:, 1] )
y[:, 2] = np.sin(y[:, 2] ) + np.cos(y[:, 2])

fig, ax = plt.subplots()
plt.plot(x,y)
plt.show()
Run Code Online (Sandbox Code Playgroud)

使用数组的 plt.plot

但是,如果我尝试根据生成动画的需要设置数据,.set_data则会遇到问题:

import matplotlib.pyplot as plt
import numpy as np


x = np.linspace(0, 2 * np.pi, 100).reshape(-1, 1)
x = np.concatenate([x] * 3, axis=1)

# generate 3 curves
y = np.copy(x)
y[:, 0] = np.cos(y[:, 0])
y[:, 1] = np.sin(y[:, 1] )
y[:, 2] = np.sin(y[:, 2] ) + np.cos(y[:, 2])

fig, ax = plt.subplots()
p, = plt.plot([], [], color='b')
p.set_data(x, y)
plt.show()

Run Code Online (Sandbox Code Playgroud)

问题

有没有办法set_data处理二维数组?虽然我知道我可以只创建三个绘图p1, p2, p3set_data循环调用每个绘图,但我的真实数据包含 1000-10,000 条要绘制的线,这使得动画太慢。

非常感谢您的帮助。

r-b*_*ers 6

set_data() 给出的数组将是两个一维数组,因此在这种情况下将需要三个 set_data()。

import matplotlib.pyplot as plt
from matplotlib.animation import FuncAnimation
import numpy as np

x = np.linspace(0, 2 * np.pi, 100).reshape(-1, 1)
x = np.concatenate([x] * 3, axis=1)

# generate 3 curves
y = np.copy(x)
y[:, 0] = np.cos(y[:, 0])
y[:, 1] = np.sin(y[:, 1] )
y[:, 2] = np.sin(y[:, 2] ) + np.cos(y[:, 2])

fig, ax = plt.subplots()
ax = plt.axes(xlim=(0,6), ylim=(-1.5, 1.5))
line1, = ax.plot([], [], lw=2)
line2, = ax.plot([], [], lw=2)
line3, = ax.plot([], [], lw=2)


def animate(i):
    line1.set_data(x[:i, 0], y[:i, 0])
    line2.set_data(x[:i, 1], y[:i, 1])
    line3.set_data(x[:i, 2], y[:i, 2])
    return line1,line2,line3

anim = FuncAnimation(fig, animate, frames=100, interval=200, repeat=False)
plt.show()
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述


Joh*_*anC 6

一种方法可能是创建对象列表并在循环中Line2D使用。set_data请注意,ax.plot()即使仅绘制了一条线,也始终返回线列表。

import matplotlib.pyplot as plt
from matplotlib.animation import FuncAnimation
import numpy as np

x = np.linspace(0, 2 * np.pi, 100)

# generate 10 curves
y = np.sin(x.reshape(-1, 1) + np.random.uniform(0, 2 * np.pi, (1, 10)))

fig, ax = plt.subplots()
ax.set(xlim=(0, 2 * np.pi), ylim=(-1.5, 1.5))
# lines = [ax.plot([], [], lw=2)[0] for _ in range(y.shape[1])]
lines = ax.plot(np.empty((0, y.shape[1])), np.empty((0, y.shape[1])), lw=2)

def animate(i):
    for line_k, y_k in zip(lines, y.T):
        line_k.set_data(x[:i], y_k[:i])
    return lines

anim = FuncAnimation(fig, animate, frames=x.size, interval=200, repeat=False)
plt.show()
Run Code Online (Sandbox Code Playgroud)