使用 matplotlib 绘制本轮

Plotting epicycles by using matplotlib

为什么下面的代码不起作用?

我想用matplotlib显示本轮,如下图

import matplotlib.pyplot as plt
import numpy as np
from numpy import *
import math


freqList = [1,2,3]
ampList = [1,2,4]
phaseList = [0,10,20]

circles = [] #create list of circles

x = 0
y = 0
for i in range(len(freqList)):
   prevx = x
   prevy = y
   theta = np.linspace( 0 , 2 * np.pi , 150 )
   x += ampList[i] * np.cos( theta*freqList[i] + phaseList[i] )
   y += ampList[i] * np.sin( theta*freqList[i] + phaseList[i] )

   circle = plt.Circle((prevx, prevy), ampList[i], fill=False)
   circles.append(circle)

   plt.figure()
   fig, ax = plt.subplots()
   ax.add_patch(circles[i])
   plt.axis("equal")
   plt.xlim( -10 , 10 ) 
   plt.ylim( -10 , 10 ) 
   plt.show()

提前感谢任何可以给我一些想法的人!

我对您的代码进行了一些更改:

  • for i in range(len(list_name)) 遍历列表的元素,然后用 list_name[i] 得到第 ith 个元素,但它是一个有点尴尬;在 python 中,您可以直接遍历列表的元素:for element in list。如果你需要遍历多个列表的元素,你可以使用zipfor a, b in zip(list_a, list_b)

  • 在你的循环中,你一次生成一个圆圈,并将其添加到绘图中。只创建一次(不是每个周期都创建一次)的东西必须在 for 循环之外生成; figax

    就是这种情况
  • 在您的代码中,您创建了一个数组 theta,它有 150 个元素。在 for 循环中,将 theta 的函数添加到 xy 中,它也是一个数组。因此,在第一次迭代中 xyint 并且表示第一个圆的坐标,然后它们成为数组。这就是您的代码抛出错误的原因

  • 如果您使用 matplotlib.patches.Circle you need only the coordinates of the center and the radius. No need to compute theta, no need to use freqList (if I interpreted it correctly). For this reason, inside the loop you have only to pass current center coordinates and radius to matplotlib.patches.Circle 并仅使用当前振幅和相位计算下一个圆的中心坐标

也就是说,您的代码变为:

# import
import matplotlib.pyplot as plt
import numpy as np

# amplitude and phase definition
ampList = [1,2,4]
phaseList = [0,10,20]

# center coordinates of the first circle
C_x = 0
C_y = 0

# generate figure and axis
fig, ax = plt.subplots()

# loop over each amplitude and phase
for amp, phase in zip(ampList, phaseList):

    # draw current circle
    circle = plt.Circle((C_x, C_y), amp, fill = False)
    ax.add_patch(circle)
    # draw current circle center
    ax.plot(C_x, C_y, marker = 'o', markerfacecolor = 'k', markeredgecolor = 'k')

    # compute next circle center 
    C_x += amp*np.cos(np.deg2rad(phase))
    C_y += amp*np.sin(np.deg2rad(phase))

# adjust axis
plt.axis("equal")
plt.xlim( -10 , 10 )
plt.ylim( -10 , 10 )

# show the plot
plt.show()