3D 散点动画仅对元组、matplotlib 中的第一个条目进行动画处理
3D scatter animation only animates first entry in tuple, matplotlib
我正在尝试设置 3D 散点图动画,按照此处的示例:
我整理了以下代码:
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.animation as animation
from mpl_toolkits.mplot3d import Axes3D
def terminal_w(r):
"""calculation of droplet terminal fallspeed"""
w=X1*r**2
return(w)
class drop():
"""class of a drop"""
def __init__(self,xpos,ypos,zpos,rad):
self.x,self.y,self.z=xpos,ypos,zpos # position
self.r=rad # radius
self.w=terminal_w(rad) # velocity
def main():
# dimensions of the domain
global xsize,ysize,zsize
global X1,X2,X3
global dt # timestep
global rho_l
xsize,ysize,zsize=1.,1.,100. # domain size in meters
X1,X2,X3=1.2e8,8e3,250. # terminal velocity coeffs
dt=10.0
rho_l=1000. # density of liquid water
#
# Student exercise 1: change radii and liquid water amount:
#
liq=1.e-3 # cloud liq water content in kg/m**3
rsmall=5.e-6 # microns
rlarge=20.e-6
# L=N*rho_l*4/3 pi r^3
ndrop=10 # total number of drops
# initial number of large drops with rlarge
# not used if distrbution of drop sizes assumed
nlarge=1
# initial random positions:
# could use a dictionary, but don't want to lose numpy advantage?
dropx=np.random.uniform(low=0,high=xsize,size=ndrop)
dropy=np.random.uniform(low=0,high=ysize,size=ndrop)
dropz=np.random.uniform(low=0,high=zsize,size=ndrop)
# one large drop falling through a cloud of small drops
dropr=np.full(ndrop,fill_value=rsmall)
dropr[-nlarge:]=rlarge
# Student exercise 2: change distribution:
# can insert code here to simply set a distribution of radii:
# set arrange from lognormal distribution,
# dropr=np.random.DIST(moments)
# initial drop conditions
drops=drop(dropx,dropy,dropz,dropr)
# set up plot window
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
ax.set_xlim(0,xsize)
ax.set_ylim(0,ysize)
ax.set_zlim(0,zsize)
sc3d=ax.scatter(drops.x,drops.y,drops.z,c='blue',marker='o')
title = ax.set_title('3D Test')
def animate(i):
timestep(drops)
print(drops.z[0])
sc3d._offsets3d=(drops.x,drops.y,drops.z) # update the data
title.set_text('3D Test, time={}'.format(i))
ani = animation.FuncAnimation(fig, animate,
interval=25,
blit=False)
plt.show()
def timestep(drops):
#print(drops.w)
drops.z-=dt*drops.w
#print(drops.z)
main()
这会生成一个 3D 散点图,但仅对其中一个标记进行动画处理,即使所有条目的 z 坐标都已更新(当我取消选中打印语句时)。
更奇怪的是,如果我注释掉语句
title.set_text('3D Test, time={}'.format(i))
在动画功能中,none 的水滴是动画的。我不明白为什么添加 title 语句允许一个标记进行动画处理,而且我看不出我的代码与对我起作用并为所有点设置动画的示例有何不同...
根据 docs,您的 animate
函数签名应该是 def func(frame, *fargs) -> iterable_of_artists
。但是,您不会返回可迭代的艺术家。您没有返回任何东西!
编辑:需要说明的是,您的函数签名是 func(frame) -> None
。哦,不要使用 globals
,它们是邪恶的。
我正在尝试设置 3D 散点图动画,按照此处的示例:
我整理了以下代码:
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.animation as animation
from mpl_toolkits.mplot3d import Axes3D
def terminal_w(r):
"""calculation of droplet terminal fallspeed"""
w=X1*r**2
return(w)
class drop():
"""class of a drop"""
def __init__(self,xpos,ypos,zpos,rad):
self.x,self.y,self.z=xpos,ypos,zpos # position
self.r=rad # radius
self.w=terminal_w(rad) # velocity
def main():
# dimensions of the domain
global xsize,ysize,zsize
global X1,X2,X3
global dt # timestep
global rho_l
xsize,ysize,zsize=1.,1.,100. # domain size in meters
X1,X2,X3=1.2e8,8e3,250. # terminal velocity coeffs
dt=10.0
rho_l=1000. # density of liquid water
#
# Student exercise 1: change radii and liquid water amount:
#
liq=1.e-3 # cloud liq water content in kg/m**3
rsmall=5.e-6 # microns
rlarge=20.e-6
# L=N*rho_l*4/3 pi r^3
ndrop=10 # total number of drops
# initial number of large drops with rlarge
# not used if distrbution of drop sizes assumed
nlarge=1
# initial random positions:
# could use a dictionary, but don't want to lose numpy advantage?
dropx=np.random.uniform(low=0,high=xsize,size=ndrop)
dropy=np.random.uniform(low=0,high=ysize,size=ndrop)
dropz=np.random.uniform(low=0,high=zsize,size=ndrop)
# one large drop falling through a cloud of small drops
dropr=np.full(ndrop,fill_value=rsmall)
dropr[-nlarge:]=rlarge
# Student exercise 2: change distribution:
# can insert code here to simply set a distribution of radii:
# set arrange from lognormal distribution,
# dropr=np.random.DIST(moments)
# initial drop conditions
drops=drop(dropx,dropy,dropz,dropr)
# set up plot window
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
ax.set_xlim(0,xsize)
ax.set_ylim(0,ysize)
ax.set_zlim(0,zsize)
sc3d=ax.scatter(drops.x,drops.y,drops.z,c='blue',marker='o')
title = ax.set_title('3D Test')
def animate(i):
timestep(drops)
print(drops.z[0])
sc3d._offsets3d=(drops.x,drops.y,drops.z) # update the data
title.set_text('3D Test, time={}'.format(i))
ani = animation.FuncAnimation(fig, animate,
interval=25,
blit=False)
plt.show()
def timestep(drops):
#print(drops.w)
drops.z-=dt*drops.w
#print(drops.z)
main()
这会生成一个 3D 散点图,但仅对其中一个标记进行动画处理,即使所有条目的 z 坐标都已更新(当我取消选中打印语句时)。
更奇怪的是,如果我注释掉语句
title.set_text('3D Test, time={}'.format(i))
在动画功能中,none 的水滴是动画的。我不明白为什么添加 title 语句允许一个标记进行动画处理,而且我看不出我的代码与对我起作用并为所有点设置动画的示例有何不同...
根据 docs,您的 animate
函数签名应该是 def func(frame, *fargs) -> iterable_of_artists
。但是,您不会返回可迭代的艺术家。您没有返回任何东西!
编辑:需要说明的是,您的函数签名是 func(frame) -> None
。哦,不要使用 globals
,它们是邪恶的。