如何在 3D 散点图中对文本进行动画处理?
How to Animate Text in 3D Scatter Plot?
我想制作 3D 散点图的动画,其中每个数据点都有一个文本标签随之移动。
现在文本标签 do 按照我的意愿跟随数据点,但它们在每一帧中都存在;文本不会从上次动画更新中消失。见下图。数据点本身移动得很好。
2 个问题的答案可能对我有帮助>
- 有什么方法可以在不清除数据点的情况下清除文本吗?
- 我的实现似乎有点笨拙。是否有类似于 _offset3d 的隐藏函数适用于文本对象。
这是绘图函数:
def graph(data, update_cnt):
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
dots = ax.scatter(data[0][0][:], data[1][0][:], data[2][0][:])
dot_txt = nmp.ones(nmp.size(data,2), dtype=str)
for n in range(0,nmp.size(data, 2)):
dot_txt[n] = ax.text(data[0][0][n], data[1][0][n], data[2][0][n],'%s'%(n))
ani = animation.FuncAnimation(fig, update, update_cnt, fargs=(dots, data, dot_txt, ax), interval=300)
plt.show()
和动画更新功能:
def update(num, dots, data, dot_txt, ax):
y = data[0][num][:]
x = data[1][num][:]
z = data[2][num][:]
dots._offsets3d = (x, y, z)
#dot_txt._something_to_update_text_here()
dot_txt = nmp.ones(nmp.size(data,2), dtype=str)
for n in range(0,nmp.size(data, 2)):
dot_txt[n] = ax.text(data[1][num][n], data[0][num][n], data[2][num][n],'%s'%(n))
和当前绘图输出:
我找到了解决办法。
我认为重要的是要注意我不能对 3D 动画散点图使用更常见的解决方案,因为我需要为不同的点使用不同的标记样式。这迫使我迭代地绘制每个散点,而不是将列表传递给更新函数。然而这样做,动画文本的问题就很好地解决了。
frame_list 包含每个帧中每个数据点的 x、y、z 坐标和样式。
def graph(frame_list):
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
frame_cnt = len(frame_list)
ani = animation.FuncAnimation(fig, update_graph, frame_cnt,
fargs=(frame_list, ax, frame_cnt), interval=600)
plt.show()
成功的最大贡献者是每帧之前的 ax.clear() 调用。
def update_graph(f, frame_list, ax, cnt):
ax.clear()
f = nmp.mod(f, cnt)
frame = frame_list[f]
for n in range(len(frame.marker)):
x, y, z, s, c, m, name = frame.get_params(n)
ax.scatter(x, y, z, s=s, c=c, marker=m)
ax.text(x, y, z, '%s'%(name))
get_params函数returns该帧的所有相关数据。
我想制作 3D 散点图的动画,其中每个数据点都有一个文本标签随之移动。
现在文本标签 do 按照我的意愿跟随数据点,但它们在每一帧中都存在;文本不会从上次动画更新中消失。见下图。数据点本身移动得很好。
2 个问题的答案可能对我有帮助>
- 有什么方法可以在不清除数据点的情况下清除文本吗?
- 我的实现似乎有点笨拙。是否有类似于 _offset3d 的隐藏函数适用于文本对象。
这是绘图函数:
def graph(data, update_cnt):
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
dots = ax.scatter(data[0][0][:], data[1][0][:], data[2][0][:])
dot_txt = nmp.ones(nmp.size(data,2), dtype=str)
for n in range(0,nmp.size(data, 2)):
dot_txt[n] = ax.text(data[0][0][n], data[1][0][n], data[2][0][n],'%s'%(n))
ani = animation.FuncAnimation(fig, update, update_cnt, fargs=(dots, data, dot_txt, ax), interval=300)
plt.show()
和动画更新功能:
def update(num, dots, data, dot_txt, ax):
y = data[0][num][:]
x = data[1][num][:]
z = data[2][num][:]
dots._offsets3d = (x, y, z)
#dot_txt._something_to_update_text_here()
dot_txt = nmp.ones(nmp.size(data,2), dtype=str)
for n in range(0,nmp.size(data, 2)):
dot_txt[n] = ax.text(data[1][num][n], data[0][num][n], data[2][num][n],'%s'%(n))
和当前绘图输出:
我找到了解决办法。
我认为重要的是要注意我不能对 3D 动画散点图使用更常见的解决方案,因为我需要为不同的点使用不同的标记样式。这迫使我迭代地绘制每个散点,而不是将列表传递给更新函数。然而这样做,动画文本的问题就很好地解决了。
frame_list 包含每个帧中每个数据点的 x、y、z 坐标和样式。
def graph(frame_list):
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
frame_cnt = len(frame_list)
ani = animation.FuncAnimation(fig, update_graph, frame_cnt,
fargs=(frame_list, ax, frame_cnt), interval=600)
plt.show()
成功的最大贡献者是每帧之前的 ax.clear() 调用。
def update_graph(f, frame_list, ax, cnt):
ax.clear()
f = nmp.mod(f, cnt)
frame = frame_list[f]
for n in range(len(frame.marker)):
x, y, z, s, c, m, name = frame.get_params(n)
ax.scatter(x, y, z, s=s, c=c, marker=m)
ax.text(x, y, z, '%s'%(name))
get_params函数returns该帧的所有相关数据。