Issue
Why does the following code not working?
I want to display epicycles by using matplotlib like a following image
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()
Thank you in advance to any one who may be able to give me some ideas!
Solution
I applied some changes to your code:
loop over elements of a list with
for i in range(len(list_name))
and then get ith element withlist_name[i]
works, but it is a little awkward; in python you can loop over elements of list directly:for element in list
. If you need to loop over element of more than one list, you can usezip
:for a, b in zip(list_a, list_b)
within your loop you generates the circles, once at a time, and add it to the plot. Things which are created only once (not once every cycle) have to be generated outside the for loop; that's the case for
fig
,ax
etc.in your code you have created an array,
theta
, which is 150 elements. Inside for loop you add up a function oftheta
, which is an array too, tox
andy
. So, in the first iterationx
andy
areint
and represent coordinates of the first circle, then they become arrays. This is the reason why your code throws an errorif you use
matplotlib.patches.Circle
you need only the coordinates of the center and the radius. No need to compute theta, no need to usefreqList
(if I interpreted it correctly). For this reason, inside the loop you have only to pass current center coordinates and radius tomatplotlib.patches.Circle
and compute center coordinates for the next circle using only current amplitude and phase
That being said, your code becomes:
# 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()
Answered By - Zephyr
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.