使用 matplotlib 制作函数切线运动的 Python 动画
最编程
2024-04-22 09:33:07
...
【直播预告】上云 vs 下云:降本增笑?割韭菜?
原文链接: Python 使用matplotlib 绘制函数切线运动动画
上一篇: atom Python 代码运行插件 scripts
下一篇: pycharm 关闭科学模式
效果
from sympy import *
from matplotlib import pyplot as plt
from matplotlib import animation
import numpy as np
# 我们的数据是一个0~2π内的正弦曲线
x = symbols('x')
y = (x - 1) * (x - 2) * (x - 3)
fig, ax = plt.subplots()
xx = np.linspace(0, 4, 500)
# 函数图像
fun, = plt.plot(xx, [y.evalf(subs={x: i}) for i in xx])
def getLine(i=0):
a, b = xx[i], y.evalf(subs={x: xx[i]})
k = diff(y, x).evalf(subs={x: a})
xdom = np.linspace(a - 1, a + 1)
ydom = k * (xdom - a) + b
return (xdom, ydom)
# 切线
xdom, ydom = getLine()
line, = plt.plot(xdom, ydom)
# 切点
point, = plt.plot(0, np.sin(0), 'ro')
# 接着,构造自定义动画函数animate,
# 用来更新每一帧上各个x对应的y坐标值,参数表示第i帧
def animate(i=0):
point.set_xdata(xx[i])
point.set_ydata(y.evalf(subs={x: xx[i]}))
xdom, ydom = getLine(i)
line.set_xdata(xdom)
line.set_ydata(ydom)
# 接下来,我们调用FuncAnimation函数生成动画。
# 参数说明: #fig 进行动画绘制的figure
# func 自定义动画函数,
# 即传入刚定义的函数animate #frames 动画长度,
# 一次循环包含的帧数 #init_func 自定义开始帧,
# 即传入刚定义的函数init #interval 更新频率,
# 以ms计 #blit 选择更新所有点,还是仅更新产生变化的点。
# 应选择True,但mac用户请选择False,否则无法显示动画
ani = animation.FuncAnimation(fig=fig,
func=animate,
frames=len(xx),
interval=20,
repeat=False,
blit=False)
plt.show()
如果在动画函数中绘制的话,是叠加效果
from sympy import *
from matplotlib import pyplot as plt
from matplotlib import animation
import numpy as np
# 我们的数据是一个0~2π内的正弦曲线
x = symbols('x')
y = (x - 1) * (x - 2) * (x - 3)
fig, ax = plt.subplots()
xx = np.linspace(0, 4, 500)
# 函数图像
fun, = plt.plot(xx, [y.evalf(subs={x: i}) for i in xx])
def getLine(i=0):
a, b = xx[i], y.evalf(subs={x: xx[i]})
k = diff(y, x).evalf(subs={x: a})
xdom = np.linspace(a - 1, a + 1)
ydom = k * (xdom - a) + b
return (xdom, ydom)
def animate(i=0):
xdom, ydom = getLine(i)
plt.plot(xdom, ydom)
plt.plot(xx[i], y.evalf(subs={x: xx[i]}), 'ro')
ani = animation.FuncAnimation(fig=fig,
func=animate,
frames=len(xx),
interval=20,
repeat=False,
blit=False)
plt.show()