python - "Tuple object is not callable"尝试使用 _offsets3d 更新 3d 散点图时

标签 python animation 3d tuples typeerror

我正在尝试创建一个(非常)简单的N-body模拟并在3D中为其设置动画。这是我的代码:

from mpl_toolkits.mplot3d import Axes3D

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

G=6.67408e-11
msol=1.989e40
mter=5.972e24
au=1.496e11
dt=.0007
N=30
positions=np.random.rand(N,3)
velocities=np.random.randn(N,3)
acc=np.zeros_like(positions)
masses=np.random.rand(N)

def gravforce(m0,m1,pos0,pos1):
    global G
    dx=pos1[0]-pos0[0]
    dy=pos1[1]-pos0[1]
    dz=pos1[2]-pos0[2]
    r=np.sqrt(dx**2+dy**2+dz**2)
    f=-G*m0*m1/r**2
    ratio=f/r
    fx=dx*ratio
    fy=dy*ratio
    fz=dz*ratio
    return fx, fy, fz

fig,ax=plt.subplots(subplot_kw=dict(projection='3d'))
planets=ax.scatter(positions[:,0],positions[:,1],positions[:,2],c='b',marker='o')

def animate(i):
    acc[:,0]=[sum([gravforce(masses[i],masses[j],positions[i],positions[j])[0]/masses[j] for j in range(1,N) if j != i]) for i in range(len(acc))]
    acc[:,1]=[sum([gravforce(masses[i],masses[j],positions[i],positions[j])[1]/masses[j] for j in range(1,N) if j != i]) for i in range(len(acc))]
    acc[:,2]=[sum([gravforce(masses[i],masses[j],positions[i],positions[j])[2]/masses[j] for j in range(1,N) if j != i]) for i in range(len(acc))]

    velocities[:,0]=velocities[:,0]+acc[:,0]*dt
    velocities[:,1]=velocities[:,1]+acc[:,1]*dt
    velocities[:,2]=velocities[:,2]+acc[:,2]*dt        

    positions[:,0]=positions[:,0]+velocities[:,0]*dt
    positions[:,1]=positions[:,1]+velocities[:,1]*dt
    positions[:,2]=positions[:,2]+velocities[:,2]*dt

    planets.set_sizes(masses[:]*20)
    planets._offsets3d(positions[:,0],positions[:,1],positions[:2])

ani=FuncAnimation(fig,animate,frames=1000,interval=1,blit=False)

当我运行它时,我收到以下错误消息:

Traceback (most recent call last):

File "<ipython-input-30-b2a4f400dbe9>", line 1, in <module>
runfile('C:/Program Files (x86)/WinPython-64bit-3.3.5.9/python-3.3.5.amd64/Scripts/orbit/3dnbody_2dprojection.py', wdir='C:/Program Files (x86)/WinPython-64bit-3.3.5.9/python-3.3.5.amd64/Scripts/orbit')

File "C:\Program Files (x86)\WinPython-64bit-3.3.5.9\python-3.3.5.amd64\lib\site-packages\spyderlib\widgets\externalshell\sitecustomize.py", line 685, in runfile
execfile(filename, namespace)

File "C:\Program Files (x86)\WinPython-64bit-3.3.5.9\python-3.3.5.amd64\lib\site-packages\spyderlib\widgets\externalshell\sitecustomize.py", line 85, in execfile
exec(compile(open(filename, 'rb').read(), filename, 'exec'), namespace)

File "C:/Program Files (x86)/WinPython-64bit-3.3.5.9/python-3.3.5.amd64/Scripts/orbit/3dnbody_2dprojection.py", line 56, in <module>
ani=FuncAnimation(fig,animate,frames=1000,interval=1,blit=False)

File "C:\Program Files (x86)\WinPython-64bit-3.3.5.9\python-3.3.5.amd64\lib\site-packages\matplotlib\animation.py", line 1067, in __init__
TimedAnimation.__init__(self, fig, **kwargs)

File "C:\Program Files (x86)\WinPython-64bit-3.3.5.9\python-3.3.5.amd64\lib\site-packages\matplotlib\animation.py", line 913, in __init__
*args, **kwargs)

File "C:\Program Files (x86)\WinPython-64bit-3.3.5.9\python-3.3.5.amd64\lib\site-packages\matplotlib\animation.py", line 591, in __init__
self._init_draw()

File "C:\Program Files (x86)\WinPython-64bit-3.3.5.9\python-3.3.5.amd64\lib\site-packages\matplotlib\animation.py", line 1092, in _init_draw
self._draw_frame(next(self.new_frame_seq()))

File "C:\Program Files (x86)\WinPython-64bit-3.3.5.9\python-3.3.5.amd64\lib\site-packages\matplotlib\animation.py", line 1106, in _draw_frame
self._drawn_artists = self._func(framedata, *self._args)  

File "C:/Program Files (x86)/WinPython-64bit-3.3.5.9/python-3.3.5.amd64/Scripts/orbit/3dnbody_2dprojection.py", line 54, in animate
planets._offsets3d(positions[:,0],positions[:,1],positions[:2])

TypeError: 'tuple' object is not callable

据我所知,我没有调用元组(根据我的理解,这将尝试执行例如 F(2) 而不是 F[2],其中 F 是一个元组),这就是为什么这对我来说既令人困惑又令人沮丧。

我也欢迎任何有关如何使此代码更加优雅/高效的热门提示。

最佳答案

看来错误来自这一行

planets._offsets3d(positions[:,0],positions[:,1],positions[:2])

根据this answerthis answer , _offsets3d 是一个私有(private)的未记录属性,它是一个包含坐标的元组,这意味着它不可调用。

为什么要尝试调用_offsets3d之类的函数?

如果您尝试设置值,可以使用以下命令:

planets._offsets3d = (positions[:,0], positions[:,1], positions[:2])

关于python - "Tuple object is not callable"尝试使用 _offsets3d 更新 3d 散点图时,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52906072/

相关文章:

python - uwsgi 的 Django 日志文件权限

python - 升级 Google Application Engine 程序以使用 unicode

animation - JavaFX ProgressBar 动画或过渡

ios - 如何使用 UILabel 创建发光效果?

javascript - 从对象面 Three.js 中检索纹理贴图坐标

ipad - 将地球的卫星照片转换为球体上的纹理贴图(OpenGL ES)

python - 排列几个 Pandas 数据框

python - Pandas :在没有副本的情况下对分层索引进行切片

html - Bootstrap 4 下拉菜单动画从页面外开始

android - 如何将 Celestia 构建到 Android?