绘制以部分定义的函数的plot_surface动画

huangapple go评论106阅读模式
英文:

Animating plot_surface of section-wise defined function

问题

我已经绘制了曲面,但不知道如何制作动画。也许我已经过于复杂化了一些事情,可以更加优雅地完成。以下是到目前为止的代码:

  1. import matplotlib.pyplot as plt
  2. import numpy as np
  3. import matplotlib.animation
  4. fig = plt.figure()
  5. ax = fig.add_subplot(111, projection='3d')
  6. x_data = np.linspace(-30, 30, 100)
  7. y_data = np.linspace(-30, 30, 100)
  8. t = np.linspace(0, 35, 100)
  9. x, y = np.meshgrid(x_data, x_data)
  10. z = np.zeros([100, 100])
  11. # 填充z值,也许可以更加优雅地完成
  12. for i in range(100):
  13. for j in range(100):
  14. if np.sqrt(x[i, j]**2 + y[i, j]**2) < t[i]:
  15. z[i, j] = np.sin(np.sqrt(x[i, j]**2 + y[i, j]**2) - t[i]) * np.exp(-t[i] / 10.)
  16. elif np.sqrt(x[i, j]**2 + y[i, j]**2) > t[i]:
  17. z[i, j] = 0
  18. dataSet = np.array([x, y, z])
  19. line = ax.plot_surface(dataSet[0], dataSet[1], dataSet[2], cmap="plasma")
  20. def update(n):
  21. line.set_data(dataSet[0:2, :n])
  22. line.set_3d_properties(dataSet[2, :n])
  23. return line,
  24. ani = matplotlib.animation.FuncAnimation(fig, update, interval=30, blit=True)

所以我的问题是,我不知道如何使更新函数或动画本身运行起来。我在互联网上找到了一些教程,但大多数都比较混乱,不如有帮助。也许我的问题甚至更加基本(比如z值的初始化,对此也不是百分之百确定),所以任何帮助都将不胜感激。

英文:

I have a given function f(x,y,t) with f=exp(-t/10)* sin(sqrt(x²+y²)-t) where sqrt(x²+y²)<t and f=0 else (if greater than t).
x and y range from -30 to 30 and t from 0 to 35. My goal is to animate the surface over the time.

I already have plotted the surface but dont' know how to animate it. Maybe I already overcomplicated some things which could be done more elegantly. Here's my code so far:

  1. import matplotlib.pyplot as plt
  2. import numpy as np
  3. import matplotlib.animation
  4. fig = plt.figure()
  5. ax = fig.add_subplot(111, projection=&#39;3d&#39;)
  6. x_data = np.linspace(-30,30,100)
  7. y_data = np.linspace(-30,30,100)
  8. t = np.linspace(0,35,100)
  9. x, y = np.meshgrid(x_data, x_data)
  10. z = np.zeros([100,100])
  11. #filling in the values for z maybe this could be done more elegantly
  12. for i in range(100):
  13. for j in range(100):
  14. if np.sqrt(x[i,j]**2+y[i,j]**2) &lt; t[i]:
  15. z[i,j] = np.sin(np.sqrt(x[i,j]**2+y[i,j]**2) -t[i]) * np.exp(-t[i]/10.)
  16. elif np.sqrt(x[i,j]**2+y[i,j]**2) &gt; t[i]:
  17. z[i,j] = 0
  18. dataSet = np.array([x, y, z])
  19. line = ax.plot_surface(dataSet[0], dataSet[1], dataSet[2], cmap=&quot;plasma&quot;)
  20. &quot;&quot;&quot;this doesn&#39;t work because line is a mpl_toolkits.mplot3d.art3d.Poly3Dcollection object. We learned this kind of update function in our university-script for another example where line was a mpl_toolkits.mplot3d.art3d.Line3D object&quot;&quot;&quot;
  21. def update(n):
  22. line.set_data(dataSet[0:2, :n])
  23. line.set_3d_properties(dataSet[2, :n])
  24. return line,
  25. ani = matplotlib.animation.FuncAnimation(fig, update, interval = 30, blit = True)

So my problem is, I don't know, how to get the update function or the animation itself up and running. I found some tuts on the internet but most of them are rather confusing than helping. Maybe my problem is even more fundamental (like the initialization of the z values, not 100 percent sure about that either), so any help will be appreciated.

答案1

得分: 1

以下是要翻译的内容:

要更高效地创建z(即,不使用循环),请利用xy的二维形式,通过对整个数组执行操作。由于在np.sqrt(x**2 + y**2) < t时不存在数值问题,您可以在所有地方计算f,然后在必要时进行修正。另一个与该计算相关的变化是将t变成3D数组,它是100个100x100的数组,每个数组都是该时间步长下的常数值的t。有了这个,您可以遍历z以进行动画。

  1. import matplotlib.pyplot as plt
  2. import numpy as np
  3. from matplotlib.animation import FuncAnimation
  4. plt.close("all")
  5. N = 100
  6. x_data = np.linspace(-30, 30, N)
  7. y_data = np.linspace(-30, 30, N)
  8. t = np.linspace(0, 35, N)
  9. x, y = np.meshgrid(x_data, x_data)
  10. t3d = np.ones((N, N, N)) * t[:, None, None]
  11. z = np.exp(-t3d / 10.) * np.sin(np.sqrt(x**2 + y**2) - t3d)
  12. z[np.sqrt(x**2 + y**2) < t3d] = 0.
  13. zmin = z.min()
  14. zmax = z.max()
  15. fig, ax = plt.subplots(subplot_kw={"projection": "3d"})
  16. def animate(i):
  17. ax.cla()
  18. ax.plot_surface(x, y, z[i])
  19. ax.set_zlim(zmin, zmax)
  20. fig.tight_layout()
  21. ani = FuncAnimation(fig, animate, frames=100, interval=30)
  22. ani.save("temp.gif", writer="pillow", fps=10, dpi=100)

绘制以部分定义的函数的plot_surface动画

英文:

To create z more efficiently (i.e. without loops), make use of the 2D form of x and y by performing the operations with those entire arrays. Since there are no numerical issues when np.sqrt(x**2 + y**2) &lt; t, you can just calculate f everywhere and then correct it afterward where necessary. One other change with that calculation is to make t 3D where it is 100 100x100 arrays, with each being a constant value for the t at that timestep. With that, you can then loop through z for the animation.

  1. import matplotlib.pyplot as plt
  2. import numpy as np
  3. from matplotlib.animation import FuncAnimation
  4. plt.close(&quot;all&quot;)
  5. N = 100
  6. x_data = np.linspace(-30, 30, N)
  7. y_data = np.linspace(-30, 30, N)
  8. t = np.linspace(0, 35, N)
  9. x, y = np.meshgrid(x_data, x_data)
  10. t3d = np.ones((N, N, N))*t[:,None,None]
  11. z = np.exp(-t3d/10.)*np.sin(np.sqrt(x**2 + y**2) - t3d)
  12. z[np.sqrt(x**2 + y**2) &lt; t3d] = 0.
  13. zmin = z.min()
  14. zmax = z.max()
  15. fig, ax = plt.subplots(subplot_kw={&quot;projection&quot;:&quot;3d&quot;})
  16. def animate(i):
  17. ax.cla()
  18. ax.plot_surface(x, y, z[i])
  19. ax.set_zlim(zmin, zmax)
  20. fig.tight_layout()
  21. ani = FuncAnimation(fig, animate, frames=100, interval=30)
  22. ani.save(&quot;temp.gif&quot;, writer=&quot;pillow&quot;, fps=10, dpi=100)

绘制以部分定义的函数的plot_surface动画

huangapple
  • 本文由 发表于 2023年6月15日 03:48:58
  • 转载请务必保留本文链接:https://go.coder-hub.com/76477082.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定