matplotlib 极轴动画

2admgd59  于 2023-10-24  发布在  其他
关注(0)|答案(3)|浏览(132)

我有这个任务:使用极坐标创建一个心脏动画。从绘制心脏开始,然后添加动画作为下一步;使用渲染Angular 的可变增加。然后我需要以同样的方式在极坐标中构建其他图形。我还需要将绘图功能与图形分开,以便可以以最小的代码更改更改图形
我试着运行这个,把输出看起来真的很奇怪,其他数字看起来不像预期当我改变theta和r.我不知道是否有可能完成这个任务使用tkinter或pygame或类似的东西.我会很高兴,如果你能想出任何想法来完成这个.

  1. import matplotlib.pyplot as plt
  2. import numpy as np
  3. import matplotlib.animation as animation
  4. fig = plt.figure()
  5. ax = fig.add_subplot(111, polar=True)
  6. theta = np.linspace(0, 2*np.pi, 100)
  7. r = 1 - (np.abs(theta) - 1) ** 2
  8. line, = ax.plot([], [], color='red')
  9. def init():
  10. line.set_data([], [])
  11. return line,
  12. def animate(i):
  13. current_theta = theta[:i]
  14. current_r = r[:i]
  15. x_polar = current_r * np.cos(current_theta)
  16. y_polar = current_r * np.sin(current_theta)
  17. line.set_data(x_polar, y_polar)
  18. return line,
  19. ani = animation.FuncAnimation(fig, animate, init_func=init, frames=len(theta), interval=50, blit=True)
  20. plt.show()
ne5o7dgx

ne5o7dgx1#

看起来你使用了错误的半径表达式。你的半径与θ的平方成正比,并且随着θ的增加而变得非常负,这在极坐标图中无法表示。最有可能的是,你缺少正弦或余弦。玩了一会儿,我发现r = 1 - (np.abs(np.cos(theta)) - 1) ** 2产生了一个心形。
一般来说,我觉得计算theta和r很奇怪,这是一个极坐标图的坐标,然后为你的图做一个类似于笛卡尔坐标(x_polar和y_polar)的变换。
关于分离问题,将半径的计算从animate函数中移出。animate函数应该只负责更新图:

  1. def heart(theta):
  2. return 1 - (np.abs(np.cos(theta)) - 1) ** 2
  3. def cardiod(theta):
  4. return 0.5 * (1 - np.sin(theta))
  5. theta = np.linspace(0, 2*np.pi, 100)
  6. r = heart(theta)
  7. # transformation needed for your example
  8. theta, r = r * np.cos(theta), r * np.sin(theta)
  9. # test of the cardiod function; this function does not need any transformation afterwards
  10. # r = cardiod(theta)
  11. def animate(i):
  12. current_theta = theta[:i]
  13. current_r = r[:i]
  14. line.set_data(current_theta, current_r)
  15. return line,

我为Cardioid on Wikipedia添加了一个函数,即“心脏曲线”,作为准备多个函数的示例。

展开查看全部
zbdgwd5y

zbdgwd5y2#

我又写了一段代码:

  1. # Import modules
  2. import numpy as np
  3. import matplotlib.pyplot as plt
  4. from matplotlib.animation import FuncAnimation
  5. # ------------------------------------------ #
  6. # Define the figure
  7. fig = plt.figure(figsize=(16,16))
  8. # Setting the axes projection as polar
  9. ax = fig.add_subplot(111, projection='polar')
  10. # Define the heart equation from https://pavpanchekha.com/blog/heart-polar-coordinates.html
  11. t = np.linspace(0.0, 2.0*np.pi, 200, endpoint=True)
  12. r = np.sin(t)*np.sqrt(np.abs(np.cos(t))) / (np.sin(t) + 7/5) - 2*np.sin(t) + 2
  13. # Define a list that stores temporary data points
  14. # [[theta], [radius]]
  15. data_points = [[], []]
  16. # Define the index of the last data point that needs to be plotted
  17. # For example, if index = 5, data_points[0][-1] = t[5] and data_points[1][-1] = r[5]
  18. index = 0
  19. def animate(i):
  20. # Global variables
  21. global data_points, index
  22. # Clear the plot
  23. ax.clear()
  24. # Remove tick labels
  25. ax.set_xticklabels([])
  26. ax.set_yticklabels([])
  27. # Append a data point to the list
  28. data_points[0].append(t[index])
  29. data_points[1].append(r[index])
  30. # Update the index
  31. index += 1
  32. # Reset the index and points
  33. # if index is out of range
  34. if (index == len(t)):
  35. index = 0
  36. data_points = [[], []]
  37. # Plot the "heart"
  38. plt.plot(data_points[0], data_points[1], color="red")
  39. # Define the limits
  40. ax.set_rlim(min(r), max(r))
  41. # Remove border
  42. #ax.axis("off")
  43. # Calling the animation function
  44. ani1 = FuncAnimation(fig, animate, interval=30)
  45. # Display the plot
  46. plt.show()

这将产生:(您必须增加theta数组中的点数以获得更平滑的线)

把你写代码的方式改成我写的..

展开查看全部
x4shl7ld

x4shl7ld3#

如果你看Desmos(link)上的图,你会发现直到pi/2,图看起来都很好,但是pi/2之后的尾端不是你想要的。所以,你需要做的第一件事是绘制从0到pi/2的theta。
你还想绘制另一半在x轴上的反射。y=f(-x)在x轴上反射f(x)。我们可以通过像在循环中一样将极坐标转换为carnival来实现这一点,然后创建点的x向量作为x坐标和负x坐标。y向量只是y坐标的两倍。为了确保绘图平滑,你会想要反转第二组点(对于x和y),这样它就不会在原点重新开始。
下面的代码做了我所描述的,我已经把代码绘制成极坐标或笛卡尔坐标。

  1. import matplotlib.pyplot as plt
  2. import numpy as np
  3. import matplotlib.animation as animation
  4. plt.close("all")
  5. fig, ax = plt.subplots(subplot_kw=dict(projection="polar"))
  6. theta = np.linspace(0, np.pi/2, 100)
  7. r = 1 - (np.abs(theta) - 1) ** 2
  8. x = r*np.cos(theta)
  9. y = r*np.sin(theta)
  10. x_data = np.concatenate((x, -x[::-1]))
  11. y_data = np.concatenate((y, y[::-1]))
  12. r_data = np.sqrt(x_data**2 + y_data**2)
  13. theta_data = np.arctan2(y_data, x_data)
  14. line, = ax.plot([], [], color='red')
  15. def init():
  16. line.set_data([], [])
  17. return line,
  18. def animate(i):
  19. # line.set_data(x_data[:i], y_data[:i]) # cartesian
  20. line.set_data(theta_data[:i], r_data[:i]) # polar
  21. return line,
  22. ani = animation.FuncAnimation(fig, animate, init_func=init, frames=len(x_data), interval=10, blit=True)
  23. plt.show()

极轴动画:

笛卡尔动画:

展开查看全部

相关问题