使用 matplotlib 动画点
Animate points with matplotlib
我想要10个移动点。我使用了下面的代码。我正在试验我不太了解的 matplotlib
。
from matplotlib import pyplot as plt
import numpy as np
from matplotlib import animation
fig = plt.figure()
ax = fig.add_subplot(projection='3d')
# second option - move the point position at every frame
def update_point(n, x, y, z, point):
point.set_data(np.array([x[n], y[n]]))
point.set_3d_properties(z[n], 'z')
return point
def x(i):
return np.cos(t*i)
for i in range(10):
t=np.arange(0, 2*np.pi, 2*np.pi/100)
y=np.sin(t)
z=t/(2.*np.pi)
point, = ax.plot([x(i)[0]], [y[0]], [z[0]], 'o')
ani=animation.FuncAnimation(fig, update_point, 99, fargs=(x(i), y, z, point))
ax.legend()
ax.set_xlim([-1.5, 1.5])
ax.set_ylim([-1.5, 1.5])
ax.set_zlim([-1.5, 1.5])
plt.show()
我希望如果我把x
变成i
的一个函数,那么我在for
循环中就会有10个点,但是什么也没有发生。只有一点在移动。我做错了什么?
首先,将动画对象 anim
放入循环中,因此不仅 point
数据而且动画对象也会被重复覆盖。为了便于使用,让我们将数据点放入 numpy 数组中,其中行代表时间,列代表您想要设置动画的不同点。然后,我们根据 t
数组计算 x
、y
和 z
数组(为了美观,沿着长度为 2*pi
的列进行无缝循环,每列移动以使点均匀分布)并在每个动画步骤中简单地更新 x
、y
和 z
数据 row-wise。与您的脚本密切相关,这看起来像:
from matplotlib import pyplot as plt
import numpy as np
from matplotlib import animation
fig = plt.figure()
ax = fig.add_subplot(projection='3d')
num_of_points = 7
num_of_frames = 50
t=np.linspace(0, 2*np.pi, num_of_frames, endpoint=False)[:, None] + np.linspace(0, 2*np.pi, num_of_points, endpoint=False)[None, :]
x=np.cos(t)
y=np.sin(t)
z=np.sin(t)*np.cos(t)
points, = ax.plot([], [], [], 'o')
def update_points(n):
points.set_data(np.array([x[n, :], y[n, :]]))
points.set_3d_properties(z[n, :], 'z')
return points,
ax.set_xlim([-1.5, 1.5])
ax.set_ylim([-1.5, 1.5])
ax.set_zlim([-1.5, 1.5])
ani=animation.FuncAnimation(fig, update_points, num_of_frames, interval=10, blit=True, repeat=True)
plt.show()
示例输出:
当你选择动画线图(这些是没有可见线的动画标记,散点图在结构上不同),你不能使用不同的颜色,除非你单独绘制每个点。从好的方面来说,您可以使用 blitting 使动画更快。
关于您的代码的另一点 - 我建议不要使用 np.arange()
,因为这会导致端点出现浮动问题。请改用 np.linspace()
。默认情况下,包含端点,但在此脚本中,我们将其更改为 False
,因此时间点 [0] 是时间点 [-1].[=33 之后 2*pi 循环中的下一步=]
对于不同的点特征,你只需要不同地填充你的数组即可。正如我所说,每个由每个点的列和不同时间点的行组成:
from matplotlib import pyplot as plt
import numpy as np
from matplotlib import animation
fig = plt.figure()
ax = fig.add_subplot(projection='3d')
num_of_points = 4
num_of_frames = 100
#different rotation frequencies
t = np.linspace(0, 2*np.pi, num_of_frames, endpoint=False)[:, None] * np.arange(1, num_of_points+1)
#different x-y centers
x = np.cos(t) + np.asarray([0, 4, 0, 3])
y = np.sin(t) + np.asarray([0, 0, 5, 2])
#different heights
z = np.zeros(num_of_frames)[:, None] + np.arange(num_of_points)
#point 4 gets random altitude fluctuations
z[:, 3] += np.random.random(num_of_frames)/5
points, = ax.plot([], [], [], 'o')
def update_points(n):
points.set_data(np.array([x[n, :], y[n, :]]))
points.set_3d_properties(z[n, :], 'z')
return points,
ax.set_xlim([x.min()-0.5, x.max()+0.5])
ax.set_ylim([y.min()-0.5, y.max()+0.5])
ax.set_zlim([z.min()-0.5, z.max()+0.5])
ani=animation.FuncAnimation(fig, update_points, num_of_frames, interval=20, blit=True, repeat=True)
plt.show()
由于时间信息是从行号派生的,您也可以忘记 t
辅助数组,直接用所需的或随机数据如下例所示。然而,对于动画,您必须确保状态之间的平滑过渡,因此沿轴 0 的增量变化是必不可少的。
...
num_of_points = 4
num_of_frames = 100
#random walk
x = np.random.random((num_of_frames, num_of_points))-0.4
y = np.random.random((num_of_frames, num_of_points))-0.3
z = np.random.random((num_of_frames, num_of_points))-0.5
x[:] = x.cumsum(axis=0)
y[:] = y.cumsum(axis=0)
z[:] = z.cumsum(axis=0)
points, = ax.plot([], [], [], 'o')
...
我想要10个移动点。我使用了下面的代码。我正在试验我不太了解的 matplotlib
。
from matplotlib import pyplot as plt
import numpy as np
from matplotlib import animation
fig = plt.figure()
ax = fig.add_subplot(projection='3d')
# second option - move the point position at every frame
def update_point(n, x, y, z, point):
point.set_data(np.array([x[n], y[n]]))
point.set_3d_properties(z[n], 'z')
return point
def x(i):
return np.cos(t*i)
for i in range(10):
t=np.arange(0, 2*np.pi, 2*np.pi/100)
y=np.sin(t)
z=t/(2.*np.pi)
point, = ax.plot([x(i)[0]], [y[0]], [z[0]], 'o')
ani=animation.FuncAnimation(fig, update_point, 99, fargs=(x(i), y, z, point))
ax.legend()
ax.set_xlim([-1.5, 1.5])
ax.set_ylim([-1.5, 1.5])
ax.set_zlim([-1.5, 1.5])
plt.show()
我希望如果我把x
变成i
的一个函数,那么我在for
循环中就会有10个点,但是什么也没有发生。只有一点在移动。我做错了什么?
首先,将动画对象 anim
放入循环中,因此不仅 point
数据而且动画对象也会被重复覆盖。为了便于使用,让我们将数据点放入 numpy 数组中,其中行代表时间,列代表您想要设置动画的不同点。然后,我们根据 t
数组计算 x
、y
和 z
数组(为了美观,沿着长度为 2*pi
的列进行无缝循环,每列移动以使点均匀分布)并在每个动画步骤中简单地更新 x
、y
和 z
数据 row-wise。与您的脚本密切相关,这看起来像:
from matplotlib import pyplot as plt
import numpy as np
from matplotlib import animation
fig = plt.figure()
ax = fig.add_subplot(projection='3d')
num_of_points = 7
num_of_frames = 50
t=np.linspace(0, 2*np.pi, num_of_frames, endpoint=False)[:, None] + np.linspace(0, 2*np.pi, num_of_points, endpoint=False)[None, :]
x=np.cos(t)
y=np.sin(t)
z=np.sin(t)*np.cos(t)
points, = ax.plot([], [], [], 'o')
def update_points(n):
points.set_data(np.array([x[n, :], y[n, :]]))
points.set_3d_properties(z[n, :], 'z')
return points,
ax.set_xlim([-1.5, 1.5])
ax.set_ylim([-1.5, 1.5])
ax.set_zlim([-1.5, 1.5])
ani=animation.FuncAnimation(fig, update_points, num_of_frames, interval=10, blit=True, repeat=True)
plt.show()
示例输出:
当你选择动画线图(这些是没有可见线的动画标记,散点图在结构上不同),你不能使用不同的颜色,除非你单独绘制每个点。从好的方面来说,您可以使用 blitting 使动画更快。
关于您的代码的另一点 - 我建议不要使用 np.arange()
,因为这会导致端点出现浮动问题。请改用 np.linspace()
。默认情况下,包含端点,但在此脚本中,我们将其更改为 False
,因此时间点 [0] 是时间点 [-1].[=33 之后 2*pi 循环中的下一步=]
对于不同的点特征,你只需要不同地填充你的数组即可。正如我所说,每个由每个点的列和不同时间点的行组成:
from matplotlib import pyplot as plt
import numpy as np
from matplotlib import animation
fig = plt.figure()
ax = fig.add_subplot(projection='3d')
num_of_points = 4
num_of_frames = 100
#different rotation frequencies
t = np.linspace(0, 2*np.pi, num_of_frames, endpoint=False)[:, None] * np.arange(1, num_of_points+1)
#different x-y centers
x = np.cos(t) + np.asarray([0, 4, 0, 3])
y = np.sin(t) + np.asarray([0, 0, 5, 2])
#different heights
z = np.zeros(num_of_frames)[:, None] + np.arange(num_of_points)
#point 4 gets random altitude fluctuations
z[:, 3] += np.random.random(num_of_frames)/5
points, = ax.plot([], [], [], 'o')
def update_points(n):
points.set_data(np.array([x[n, :], y[n, :]]))
points.set_3d_properties(z[n, :], 'z')
return points,
ax.set_xlim([x.min()-0.5, x.max()+0.5])
ax.set_ylim([y.min()-0.5, y.max()+0.5])
ax.set_zlim([z.min()-0.5, z.max()+0.5])
ani=animation.FuncAnimation(fig, update_points, num_of_frames, interval=20, blit=True, repeat=True)
plt.show()
t
辅助数组,直接用所需的或随机数据如下例所示。然而,对于动画,您必须确保状态之间的平滑过渡,因此沿轴 0 的增量变化是必不可少的。
...
num_of_points = 4
num_of_frames = 100
#random walk
x = np.random.random((num_of_frames, num_of_points))-0.4
y = np.random.random((num_of_frames, num_of_points))-0.3
z = np.random.random((num_of_frames, num_of_points))-0.5
x[:] = x.cumsum(axis=0)
y[:] = y.cumsum(axis=0)
z[:] = z.cumsum(axis=0)
points, = ax.plot([], [], [], 'o')
...