如何在同一个 matplotlib 图中绘制动画和点
How do I plot an animation and a point in the same matplotlib plot
我已经创建了 x_graph
和 y_graph
的动画情节,它绘制了行星的路径以及 x_sun
和 y_sun
的情节在同一情节 x_graph
和 y_graph
具有标记 = 'o',其中整个动画的位置是固定的,即在 (-0.8,0)。此外,我还需要将行星的运动显示为围绕太阳移动的蓝点,留下一条小轨迹,但不是其运动的完整路径。
这是我的代码,但似乎不起作用。输出只是作为动画的行星运动。我没有从 x_sun
和 y_sun
的图中得到那个蓝点,它应该在 (-0.8, 0)
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.animation as animation
n = int(input("Enter the number of steps\n"))
s = int(n/2)
def f(r, u, t):
return 1/r**3-1/r**2 # Equation of r
def g(theta, r, t):
return 1/r**2 # Equation of theta
x_graph = []
y_graph = []
x1 = []
y1 = []
def func(r_0, theta_0, u_0, t_0, h):
x = -0.98 # initial value of x
y = 0 # initial value of y
for i in range(1, n + 1):
m1 = h * u_0
k1 = h * f(r_0, u_0, t_0)
l1 = h * g(theta_0, r_0, t_0)
m2 = h * (u_0 + 0.5 * k1)
k2 = h * f(r_0 + 0.5 * m1, u_0 + 0.5 * k1, t_0 + 0.5 * h)
l2 = h * g(theta_0 + 0.5 * l1, r_0 + 0.5 * k1, t_0 + 0.5 * h)
m3 = h * (u_0 + 0.5 * k2)
k3 = h * f(r_0 + 0.5 * m2, u_0 + 0.5 * k2, t_0 + 0.5 * h)
l3 = h * g(theta_0 + 0.5 * l2, r_0 + 0.5 * k2, t_0 + 0.5 * h)
m4 = h * (u_0 + k3)
k4 = h * f(r_0 + m3, u_0 + k3, t_0 + h)
l4 = h * g(theta_0 + l3, r_0 + k3, t_0 + h)
r_0 += (m1 + 2 * m2 + 2 * m3 + m4) / 6
u_0 += (k1 + 2 * k2 + 2 * k3 + k4) / 6
theta_0 += (l1 + 2 * l2 + 2 * l3 + l4) / 6
x = r_0 * np.cos(theta_0)
y = r_0 * np.sin(theta_0)
t_0 += h
x_graph.append(x)
y_graph.append(y)
return x, y
fig = plt.figure()
p1 = fig.add_subplot(111)
l1, = p1.plot([],[])
l2, = p1.plot([],[],marker= 'o', ls='')
print(func(0.98, -np.pi, 0, 0, 0.001))
x_sun = np.linspace(-0.8, -0.8, len(x_graph))
y_sun = np.linspace(0,0,len(y_graph))
plt.xlim(-1.2,1.5)
plt.ylim(-1.5,1.5)
plt.xlabel('x axis')
plt.ylabel('y axis')
plt.title('Planet\'s orbit')
def polar_animator(i):
l1.set_data(x_graph[:i], y_graph[:i])
return l1,
def animate(i):
l2.set_data(x_sun[:i], y_sun[:i])
return l2,
ani = animation.FuncAnimation(fig, polar_animator, frames= len(x_graph), interval=1,
blit=True)
anim = animation.FuncAnimation(fig, animate, interval=1, blit=True)
ani.save('planet.mp4', writer= 'ffmpeg')
目前输出看起来像这样,但我想在点 (-0.8, 0) 处有一个标记(如大点)代表太阳。由于 SO 不允许嵌入视频,因此我无法附加视频。我附上了 .png 文件
运行 你的代码在我的机器上给出了以下输出:
有些地方看起来不对劲。
动画被调用了两次(这导致我的电脑出现闪烁)。所以只需调用一次动画并更新两个元素(事实上,您只需要触摸太阳绘图一次,这样您仍然可以每次都减少不必要的太阳绘图)。
def animate(i):
l2.set_data(x_sun[:i], y_sun[:i])
l1.set_data(x_graph[:i], y_graph[:i])
return l2,l1,
像下面这样调用一次动画函数:
anim = animation.FuncAnimation(fig, animate, frames=100, interval=1, blit=True)
我已经创建了 x_graph
和 y_graph
的动画情节,它绘制了行星的路径以及 x_sun
和 y_sun
的情节在同一情节 x_graph
和 y_graph
具有标记 = 'o',其中整个动画的位置是固定的,即在 (-0.8,0)。此外,我还需要将行星的运动显示为围绕太阳移动的蓝点,留下一条小轨迹,但不是其运动的完整路径。
这是我的代码,但似乎不起作用。输出只是作为动画的行星运动。我没有从 x_sun
和 y_sun
的图中得到那个蓝点,它应该在 (-0.8, 0)
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.animation as animation
n = int(input("Enter the number of steps\n"))
s = int(n/2)
def f(r, u, t):
return 1/r**3-1/r**2 # Equation of r
def g(theta, r, t):
return 1/r**2 # Equation of theta
x_graph = []
y_graph = []
x1 = []
y1 = []
def func(r_0, theta_0, u_0, t_0, h):
x = -0.98 # initial value of x
y = 0 # initial value of y
for i in range(1, n + 1):
m1 = h * u_0
k1 = h * f(r_0, u_0, t_0)
l1 = h * g(theta_0, r_0, t_0)
m2 = h * (u_0 + 0.5 * k1)
k2 = h * f(r_0 + 0.5 * m1, u_0 + 0.5 * k1, t_0 + 0.5 * h)
l2 = h * g(theta_0 + 0.5 * l1, r_0 + 0.5 * k1, t_0 + 0.5 * h)
m3 = h * (u_0 + 0.5 * k2)
k3 = h * f(r_0 + 0.5 * m2, u_0 + 0.5 * k2, t_0 + 0.5 * h)
l3 = h * g(theta_0 + 0.5 * l2, r_0 + 0.5 * k2, t_0 + 0.5 * h)
m4 = h * (u_0 + k3)
k4 = h * f(r_0 + m3, u_0 + k3, t_0 + h)
l4 = h * g(theta_0 + l3, r_0 + k3, t_0 + h)
r_0 += (m1 + 2 * m2 + 2 * m3 + m4) / 6
u_0 += (k1 + 2 * k2 + 2 * k3 + k4) / 6
theta_0 += (l1 + 2 * l2 + 2 * l3 + l4) / 6
x = r_0 * np.cos(theta_0)
y = r_0 * np.sin(theta_0)
t_0 += h
x_graph.append(x)
y_graph.append(y)
return x, y
fig = plt.figure()
p1 = fig.add_subplot(111)
l1, = p1.plot([],[])
l2, = p1.plot([],[],marker= 'o', ls='')
print(func(0.98, -np.pi, 0, 0, 0.001))
x_sun = np.linspace(-0.8, -0.8, len(x_graph))
y_sun = np.linspace(0,0,len(y_graph))
plt.xlim(-1.2,1.5)
plt.ylim(-1.5,1.5)
plt.xlabel('x axis')
plt.ylabel('y axis')
plt.title('Planet\'s orbit')
def polar_animator(i):
l1.set_data(x_graph[:i], y_graph[:i])
return l1,
def animate(i):
l2.set_data(x_sun[:i], y_sun[:i])
return l2,
ani = animation.FuncAnimation(fig, polar_animator, frames= len(x_graph), interval=1,
blit=True)
anim = animation.FuncAnimation(fig, animate, interval=1, blit=True)
ani.save('planet.mp4', writer= 'ffmpeg')
目前输出看起来像这样,但我想在点 (-0.8, 0) 处有一个标记(如大点)代表太阳。由于 SO 不允许嵌入视频,因此我无法附加视频。我附上了 .png 文件
运行 你的代码在我的机器上给出了以下输出:
有些地方看起来不对劲。
动画被调用了两次(这导致我的电脑出现闪烁)。所以只需调用一次动画并更新两个元素(事实上,您只需要触摸太阳绘图一次,这样您仍然可以每次都减少不必要的太阳绘图)。
def animate(i):
l2.set_data(x_sun[:i], y_sun[:i])
l1.set_data(x_graph[:i], y_graph[:i])
return l2,l1,
像下面这样调用一次动画函数:
anim = animation.FuncAnimation(fig, animate, frames=100, interval=1, blit=True)