【问题标题】:How can I animate multiple points to revolve independently around a single point?如何为多个点设置动画以围绕单个点独立旋转?
【发布时间】:2020-08-12 21:16:13
【问题描述】:

我正在尝试构建散点图,但对动画感到困惑。最终,我希望有 >1000 个点,以 (0,0) 附近的随机正态分布绘制。然后每个点应以不同的速度绕 (0,0) 顺时针或逆时针旋转。

我试图用一个随机移动的循环函数来做到这一点,但它非常慢,而且到目前为止我还无法进行超过一个点的移动:

import numpy as np
import matplotlib.pyplot as plt
plt.rcParams["figure.figsize"] = 4,3
from matplotlib.animation import FuncAnimation
from math import sqrt, exp
from matplotlib.animation import FuncAnimation, PillowWriter

fig, ax = plt.subplots()
# set the axes limits
ax.axis([-2.5,2.5,-2.5,2.5])
# set equal aspect such that the circle is not shown as ellipse
ax.set_aspect("equal")
# create a point in the axes

for i in range(0,6):
    x = np.random.normal()
    y = np.random.normal()
    r = np.sqrt(x*x+y*y)
    def circle(phi):
        return np.array([r*np.cos(phi), r*np.sin(phi)])
    point, = ax.plot(x,y, marker="o")
    ani = FuncAnimation(fig, update, interval=10, blit=True, repeat=True,
                    frames=np.linspace(0,2*np.pi,360, endpoint=False))
    
plt.show()

writer = PillowWriter(fps=25) 
ani.save(r'[path --> .gif]', writer=writer)

如何修复此代码?

【问题讨论】:

  • 你的update 不见了 - 你有这个吗?
  • 恐怕我没有。我发现更新非常令人困惑(可能是为什么我的代码不起作用!)我将如何在循环中表达它?

标签: python matplotlib animation


【解决方案1】:

这是你想要的吗?

import numpy as np
import matplotlib.pyplot as plt
plt.rcParams["figure.figsize"] = 4,3
from matplotlib.animation import FuncAnimation
from math import sqrt, exp


fig, ax = plt.subplots()
# set the axes limits
ax.axis([-2.5,2.5,-2.5,2.5])
# set equal aspect such that the circle is not shown as ellipse
ax.set_aspect("equal")
# create a point in the axes

def update(i):
    x = np.random.normal()
    y = np.random.normal()
    r = np.sqrt(x*x+y*y)
    def circle(phi):
        return np.array([r*np.cos(phi), r*np.sin(phi)])
    ax.plot(x,y, marker="o")

ani = FuncAnimation(fig, func=update, interval=10, blit=False, repeat=True,
                frames=np.linspace(0,2*np.pi,360, endpoint=False))

plt.show()

【讨论】:

  • 不完全是,但你的代码确实帮助我学会了一个一个地填充标记。谢谢。
【解决方案2】:

我不知道如何更新您的代码以获得解决方案。但我想出了这个,它使用了一些相同的逻辑:

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

# how many points to draw
points = 100

# generating x & y coordinates, their distance from origin,
# their angle relative to the origin, and random rotations to
# apply to each point each frame
xs = np.random.uniform(-1, 1, points)
ys = np.random.uniform(-1, 1, points)
ls = np.sqrt(xs**2 + ys**2)
angles = np.arctan2(ys, xs)
negs = np.random.choice([-1, 1], size=points)
rotations = (np.random.uniform(np.pi/50, np.pi/6, size=points) * negs)

# initialize a figure, make a color range to color each point
fig, ax = plt.subplots(figsize=(4,4))
ax.set_xlim(-1.5,1.5)
ax.set_ylim(-1.5,1.5)
color_divisions = [(1/points)*i for i in range(points)]
cmap = mpl.cm.get_cmap('jet')
colors = cmap(color_divisions)

# update function
# update gets fed elements from the frames parameter of FuncAnimation
# each update we clear the graph (but reapply the same x/y limits)
# we then draw the points as a scatter and update the data for the next frame
# add each rotation to each angle, and then calculate the new x and y coordinates
# with numpy these calculations can be done w/o a loop, but global is needed
# to update variables from the global scope
def update(f):
    global xs, ys, angles, rotations
    ax.clear()
    ax.set_xlim(-1.5,1.5)
    ax.set_ylim(-1.5,1.5)
    ax.scatter(xs, ys, color=colors)
    angles += rotations
    ys = np.sin(angles) * ls
    xs = np.cos(angles) * ls

#call the animation and save
ani = FuncAnimation(fig, update, interval=200, frames=range(100))
ani.save('ani.gif', writer='pillow')

产生以下 100 个点以随机速度绕原点旋转的动画:

您可以增加点数(这对于 1000 个点可能会变得很慢)、调整 FPS (interval) 或每个点的旋转量。

【讨论】:

  • 就是这样。非常感谢!
  • 我要补充的唯一问题是:是否可以将此ani保存为具有透明背景的gif? (在我的情况下,它可以插入到 Powerpoint 中以覆盖背景图像)?
  • @stimsssss 嗯,我不知道该怎么做。我见过this postthis issue,你可以看看。我无法快速让它适用于这个例子。但是,如果您无法完成某项工作,您可以打开一个新帖子(显示什么不起作用)
  • 会做@Tom 谢谢。我会继续努力,如果找到成功的答案,我会在这里发布以供日后参考。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-12-02
  • 1970-01-01
  • 1970-01-01
  • 2018-02-27
  • 1970-01-01
  • 2012-11-21
相关资源
最近更新 更多