我正在尝试从列表中读取数据时尽可能高效地动画多个补丁?
下面的代码显示散点图的动画,但不显示补丁。散点图中的每个点都包含各种大小的圆。此示例需要6个不同的圆圈,每个时间点在2个主题上进行动画处理。但是,如果有20个主题,每个主题周围有3个圆圈。
为每个帧动画所有60个圆圈的最有效方法是什么?
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.animation as animation
import matplotlib as mpl
x_data = np.random.randint(80, size=(400, 4))
y_data = np.random.randint(80, size=(400, 4))
fig, ax = plt.subplots(figsize = (8,6))
ax.set_xlim(0,80)
ax.set_ylim(0,80)
scatter = ax.scatter(x_data[0], y_data[0], zorder = 5) #Scatter plot
Player_1 = x_data[0][0], y_data[0][0]
Player_2 = x_data[0][1], y_data[0][1]
Player_1_IR = mpl.patches.Circle(Player_1, radius = 2, color = 'black', lw = 1, alpha = 0.8, zorder = 4)
Player_1_MR = mpl.patches.Circle(Player_1, radius = 4, color = 'gray', lw = 1, alpha = 0.8, zorder = 3)
Player_1_OR = mpl.patches.Circle(Player_1, radius = 6, color = 'lightgrey', lw = 1, alpha = 0.8, zorder = 2)
Player_2_IR = mpl.patches.Circle(Player_2, radius = 2, color = 'black', lw = 1, alpha = 0.8, zorder = 4)
Player_2_MR = mpl.patches.Circle(Player_2, radius = 4, color = 'gray', lw = 1, alpha = 0.8, zorder = 3)
Player_2_OR = mpl.patches.Circle(Player_2, radius = 6, color = 'lightgrey', lw = 1, alpha = 0.8, zorder = 2)
ax.add_patch(Player_1_IR)
ax.add_patch(Player_1_MR)
ax.add_patch(Player_1_OR)
ax.add_patch(Player_2_IR)
ax.add_patch(Player_2_MR)
ax.add_patch(Player_2_OR)
def animate(i) :
scatter.set_offsets(np.c_[x_data[i,:], y_data[i,:]])
ani = animation.FuncAnimation(fig, animate, frames=len(x_data),
interval = 700, blit = False)
plt.show()
答案 0 :(得分:1)
您可以将要更新的所有修补程序存储在列表中,然后通过该列表迭代每个迭代步骤。请注意,Circle
色块的大小是以数据单位/坐标为单位,而散点图以点为单位(一个点= 1/72英寸),这意味着散点和圆之间的相对大小取决于图形尺寸和轴限制,并在重新缩放图形时发生变化。
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.animation as animation
import matplotlib as mpl
x_data = np.random.randint(80, size=(400, 20))
y_data = np.random.randint(80, size=(400, 20))
fig, ax = plt.subplots(figsize = (8,6))
ax.set_xlim(0,80)
ax.set_ylim(0,80)
scatter = ax.scatter(x_data[0], y_data[0], zorder = 5) #Scatter plot
##creating list of patches
players = []
for n in range(10):
##as there are always 3 circles, append all three patches as a list at once
players.append([
mpl.patches.Circle((x_data[0,n],y_data[0,n]), radius = 2, color = 'black', lw = 1, alpha = 0.8, zorder = 4),
mpl.patches.Circle((x_data[0,n],y_data[0,n]), radius = 4, color = 'gray', lw = 1, alpha = 0.8, zorder = 3),
mpl.patches.Circle((x_data[0,n],y_data[0,n]), radius = 6, color = 'lightgrey', lw = 1, alpha = 0.8, zorder = 2)
])
##adding patches to axes
for player in players:
for circle in player:
ax.add_patch(circle)
def animate(i):
scatter.set_offsets(np.c_[x_data[i,:], y_data[i,:]])
##updating players:
for n,player in enumerate(players):
for circle in player:
circle.center = (x_data[i,n],y_data[i,n])
ani = animation.FuncAnimation(fig, animate, frames=len(x_data),
interval = 700, blit = False)
plt.show()
旧答案(视觉效果略有不同,但可以调整为相同):
如果您真的只想在散点图周围使用圆圈,那么您实际上可以忘记Circle
个补丁,只需覆盖几个不同标记尺寸的散点图。
在下面的例子中,我只是通过切片随机数组来用圆圈标记部分散点。还要记住,在散点图中,标记大小以点的平方值给出,因此如果要将圆半径从5增加到6,则给定的标记大小应从25更改为36。
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.animation as animation
import matplotlib as mpl
x_data = np.random.randint(80, size=(400, 20))
y_data = np.random.randint(80, size=(400, 20))
fig, ax = plt.subplots(figsize = (8,6))
ax.set_xlim(0,80)
ax.set_ylim(0,80)
scatter = ax.scatter(x_data[0], y_data[0], zorder = 5) #Scatter plot
scatter_IR = ax.scatter(
x_data[0,:10], y_data[0,:10], zorder = 4,
facecolor='black', edgecolor = 'black',
alpha = 0.8, s = 100
)
scatter_MR = ax.scatter(
x_data[0,:10], y_data[0,:10], zorder = 3,
facecolor='grey', edgecolor = 'grey',
alpha = 0.8, s = 225
)
scatter_OR = ax.scatter(
x_data[0,:10], y_data[0,:10], zorder = 2,
facecolor='lightgrey', edgecolor = 'lightgrey',
alpha = 0.8, s = 400
)
def animate(i) :
scatter.set_offsets(np.c_[x_data[i,:], y_data[i,:]])
scatter_IR.set_offsets(np.c_[x_data[i,:10], y_data[i,:10]])
scatter_MR.set_offsets(np.c_[x_data[i,:10], y_data[i,:10]])
scatter_OR.set_offsets(np.c_[x_data[i,:10], y_data[i,:10]])
ani = animation.FuncAnimation(fig, animate, frames=len(x_data),
interval = 700, blit = False)
plt.show()