numpy 更新直线的方程matplotlib动画

wwwo4jvm  于 2023-08-05  发布在  其他
关注(0)|答案(1)|浏览(123)

我正在尝试将泰勒级数从1项到50项动画化。我目前拥有的代码允许我指定一些术语并将其绘制到一个图上(与另一个图进行比较):

  1. import math
  2. import numpy as np
  3. import matplotlib.pyplot as plt
  4. def func_cos(x, n):
  5. cos_approx = 0
  6. for i in range(n):
  7. coef = (-1)**i
  8. num = x**(2*i)
  9. denom = math.factorial(2*i)
  10. cos_approx += ( coef ) * ( (num)/(denom) )
  11. return cos_approx
  12. def func_sin(x, n):
  13. sin_approx = 0
  14. for i in range(n):
  15. coef = (-1)**i
  16. num = x**(2*i+1)
  17. denom = math.factorial(2*i+1)
  18. sin_approx += ( coef ) * ( (num)/(denom) )
  19. return sin_approx
  20. i = 1j
  21. e = math.e
  22. x = np.linspace(0, 10, 1000)
  23. fx = e**(i*x)
  24. taylor = lambda j: np.array([func_cos(x_val,j) + i*func_sin(x_val,j) for x_val in x])
  25. plt.plot(fx.real, fx.imag)
  26. plt.plot(taylor(50).real, taylor(50).imag)
  27. plt.show()

字符串
有没有一种方法来动画的图形,使线改变方程的每一帧的泰勒级数的数目?

f2uvfpb9

f2uvfpb91#

动画模块

一种是animation模块。在这种情况下,这可能是最好的方法,因为您对第i帧应该是什么样子有了明确的定义。
下面是您的代码,更新了一些注解行。

  1. import math
  2. import numpy as np
  3. import matplotlib.pyplot as plt
  4. # You need this module
  5. import matplotlib.animation as anim
  6. def func_cos(x, n):
  7. cos_approx = 0
  8. for i in range(n):
  9. coef = (-1)**i
  10. num = x**(2*i)
  11. denom = math.factorial(2*i)
  12. cos_approx += ( coef ) * ( (num)/(denom) )
  13. return cos_approx
  14. def func_sin(x, n):
  15. sin_approx = 0
  16. for i in range(n):
  17. coef = (-1)**i
  18. num = x**(2*i+1)
  19. denom = math.factorial(2*i+1)
  20. sin_approx += ( coef ) * ( (num)/(denom) )
  21. return sin_approx
  22. i = 1j
  23. e = math.e
  24. x = np.linspace(0, 10, 1000)
  25. fx = e**(i*x)
  26. taylor = lambda j: np.array([func_cos(x_val,j) + i*func_sin(x_val,j) for x_val in x])
  27. plt.plot(fx.real, fx.imag)
  28. # You need to keep the "artist", that is the plotted line, to be able to update its data later
  29. # Note the `,`: plt.plot returns 2 things, the first being the one we want (pltdata)
  30. pltdata,=plt.plot(taylor(0).real, taylor(0).imag)
  31. # The animate function is in charge of updating the data
  32. # i is the frame number
  33. def animate(i):
  34. pltdata.set_data(taylor(i).real, taylor(i).imag)
  35. # Animate returns the list of the "artists" it has changed. So here, just [pltdata]
  36. return [pltdata]
  37. # Note the dummy "myanim" variable. Even if we don't use it afterward, it is necessary
  38. # so that the garbage collector doesn't destry the animation
  39. # plt.gcf() is just the figure. So, if you have a fig=plt.figure() somewhere, that should be replaced by `fig`
  40. # I reduced the 50 values, because, well, 20 is more than enough (at this point, you even start adding
  41. # more numerical noise that accuracy. But well, that has nothing to do with animation)
  42. myanim = anim.FuncAnimation(plt.gcf(), animate, frames=20, interval=200, blit=True)
  43. plt.show()
  44. # or myanim.save('out.mp4') to create a animation in a file

字符串
另外(见最后一行注解),animation允许轻松创建很酷的动画gif(或mp4,但需要gif来放入[so]消息),如

离子

另一种方法是使情节互动,并更新它(甚至每次从头开始重绘一切,这取决于你),使用你自己的时间策略。

  1. plt.ion()
  2. for k in range(20):
  3. plt.gcf().clear()
  4. plt.xlim(-1.5, 1.5)
  5. plt.ylim(-1.5, 1.5)
  6. plt.plot(fx.real, fx.imag)
  7. plt.plot(taylor(k).real, taylor(k).imag)
  8. plt.draw()
  9. plt.pause(0.2)


或者两者的混合

  1. plt.ion()
  2. plt.plot(fx.real, fx.imag)
  3. plt.xlim(-1.5, 1.5)
  4. plt.ylim(-1.5, 1.5)
  5. pltdata,=plt.plot(taylor(0).real, taylor(0).imag)
  6. for k in range(20):
  7. pltdata.set_data(taylor(k).real, taylor(k).imag)
  8. plt.draw()
  9. plt.pause(0.2)


请注意,我想在这里只关注动画部分。所以没有针对您的情况进行优化。例如,通过每次计算taylor(k)taylor(k)本身计算所有项,我基本上计算了30倍的常数系数,29倍的x系数,28倍的x²系数,...
显然,这是可以优化的。
比如像这样

  1. plt.ion()
  2. plt.plot(fx.real, fx.imag)
  3. plt.xlim(-1.5, 1.5)
  4. plt.ylim(-1.5, 1.5)
  5. pltdata,=plt.plot(xx, yy)
  6. fac=1.0
  7. for k in range(20):
  8. xx += (-1)**k * x**(2*k) / fac
  9. fac *= (2*k+1)
  10. yy += (-1)**k * x**(2*k+1) / fac
  11. fac *= (2*k+2)
  12. pltdata.set_data(xx,yy)
  13. plt.draw()
  14. plt.pause(0.2)

展开查看全部

相关问题