I am tasked with generating evenly (more or less) spaced points on concentric rings of an invisible circle. The function should take a list of radii, and number of points to plot for a given radius as arguments. For example for a radius of 0 it should plot 1 point at (0,0). For a circle of radius of 1, it should plot 10 points along the circumference of the circle, spaced out by an angle of 2pi/10. For a circle of radius 2, 20 points along the circumference, spaced out by an angle of 2pi/20.
The generator should take the following parameters:
n, r_max, m
and should generate rings of coordinate pairs at radii
r_i = i*r_max/n for i = 0,1,..,n.
Each ring should have n*i points uniformly distributed in θ where
n_i=1 for i=0; n_i = mi for i>0
When the function is called like this:
for r, t in genpolar.rtuniform(n=10, rmax=0.1, m=6):
plot(r * cos(t), r * sin(t), 'bo')
it should return a plot that looks like:
Here is what I've come up with so far:
def rtpairs(R, N):
R=[0.0,0.1,0.2]
N=[1,10,20]
r=[]
t=[]
for i in N:
theta=2*np.pi/i
t.append(theta)
for j in R:
j=j
r.append(j)
plt.plot(r*np.cos(t),r*np.sin(t), 'bo')
plt.show()
but I'm pretty sure there is a more efficient method using two for loops.
Many thanks
I figured it out. The code goes like this:
import numpy as np
import matplotlib.pyplot as plt
T = [1, 10, 20, 30, 40, 50, 60]
R = [0.0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6]
def rtpairs(r, n):
for i in range(len(r)):
for j in range(n[i]):
yield r[i], j*(2 * np.pi / n[i])
for r, t in rtpairs(R, T):
plt.plot(r * np.cos(t), r * np.sin(t), 'bo')
plt.show()
Here is one way to do this.
import numpy as np
import matplotlib.pyplot as plt
def circle_points(r, n):
circles = []
for r, n in zip(r, n):
t = np.linspace(0, two_pi, n)
x = r * np.cos(t)
y = r * np.sin(t)
circles.append(np.c_[x, y])
return circles
When you pass this function in the appropriate lists, one with the radius for each circle and the other with the desired number of points it returns a list of coordinate arrays, one for each circle.
r = [0, 0.1, 0.2]
n = [1, 10, 20]
circles = circle_points(r, n)
These can be plotted as follows.
fig, ax = plt.subplots()
for circle in circles:
ax.scatter(circle[:, 0], circle[:, 1])
ax.set_aspect('equal')
plt.show()
Here we see the result for more circles.
n = [1, 10, 20, 30, 40, 50, 60]
r = [0.0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6]
circles = circle_points(r, n)
fig, ax = plt.subplots()
for circle in circles:
ax.scatter(circle[:, 0], circle[:, 1])
ax.set_aspect('equal')
plt.show()
I don't know python but this formula should help.
int ringNumber = 0
int n = ringNumber-1
((n/n+1)*60)-60 = degrees between points(except for ring zero, which the point is the center
You do have to cycle through the entire circle for all radii, so your plot call is pretty much stuck with some M*N process.
The code details can be slightly improved. For starters, your R list already holds the values you want; there's no need to construct a new list with the same values. You can build the t list with a straightforward list comprehension.
Is this what you wanted?
N=[1,10,20]
t = [2*np.pi/i for i in N]
for R in N:
plt.plot(R*np.cos(t),R*np.sin(t), 'bo')
plt.show()