Как создать круг с равномерно распределенными точками по периметру с помощью scatterplot в python

1

Предположим, что у меня есть окружность x**2 + y**2 = 20. Теперь я хочу построить круг с n_dots количеством точек в круге по периметру в n_dots рассеяния. Поэтому я создал код, как показано ниже:

n_dots = 200
x1 = np.random.uniform(-20, 20, n_dots//2)
y1_1 = (400 - x1**2)**.5
y1_2 = -(400 - x1**2)**.5
plt.figure(figsize=(8, 8))
plt.scatter(x1, y1_1, c = 'blue')
plt.scatter(x1, y1_2, c = 'blue')
plt.show()

Но это показывает, что точки не равномерно распределяют все места в круге. Выход:

Изображение 174551

Итак, как создать круг с точками в области разброса, где все точки равномерно распределены по периметру круга?

Теги:
matplotlib
scatter-plot

2 ответа

1
Лучший ответ

для очень обобщенного ответа, который также работает в 2D:

import numpy as np
import matplotlib.pyplot as plt


def u_sphere_pts(dim, N):
    """
    uniform  distribution points on hypersphere
    from uniform distribution in n-D (<-1, +1>) hypercube,
    clipped by unit 2 norm to get the points inside the insphere,
    normalize selected points to lie on surface of unit radius hypersphere
    """
    # uniform points in hypercube
    u_pts = np.random.uniform(low=-1.0, high=1.0, size=(dim, N))

    # n dimensional 2 norm squared
    norm2sq = (u_pts**2).sum(axis=0)

    # mask of points where 2 norm squared  < 1.0
    in_mask = np.less(norm2sq, np.ones(N))

    # use mask to select points, norms inside unit hypersphere
    in_pts = np.compress(in_mask, u_pts, axis=1)
    in_norm2 = np.sqrt(np.compress(in_mask, norm2sq))  # only sqrt selected

    # return normalized points, equivalently, projected to hypersphere surface
    return in_pts/in_norm2


# show some 2D "sphere" points
N = 1000
dim = 2
fig2, ax2 = plt.subplots()
ax2.scatter(*u_sphere_pts(dim, N))
ax2.set_aspect('equal')
plt.show()

Изображение 174551

# plot histogram of angles

pts = u_sphere_pts(dim, 1000000)
theta = np.arctan2(pts[0,:], pts[1,:])
num_bins = 360
fig1, ax1 = plt.subplots()
n, bins, patches = plt.hist(theta, num_bins, facecolor='blue', alpha=0.5)
plt.show()

Изображение 174551

похожие/связанные: https://stackoverflow.com/questions/45580865/python-generate-an-n-dimensional-hypercube-using-rejection-sampling#comment78122144_45580865

Python Равномерное распределение точек на 4-мерной сфере

http://mathworld.wolfram.com/HyperspherePointPicking.html

Сэмплирование равномерно распределенных случайных точек внутри сферического объема

2

Простой способ построения равномерно расположенных точек по периметру круга начинается с деления всего круга на одинаково малые углы, где получаются углы от центра круга до всех точек. Затем можно вычислить координаты (x, y) каждой точки. Вот код, который выполняет задачу:

import matplotlib.pyplot as plt
import numpy as np

fig = plt.figure(figsize=(8, 8))

n_dots = 120   # set number of dots
angs = np.linspace(0, 2*np.pi, n_dots)  # angles to the dots
cx, cy = (50, 20)  # center of circle
xs, ys = [], []    # for coordinates of points to plot
ra = 20.0          # radius of circle

for ang in angs:
    # compute (x,y) for each point
    x = cx + ra*np.cos(ang)
    y = cy + ra*np.sin(ang)
    xs.append(x)   # collect x
    ys.append(y)   # collect y

plt.scatter(xs, ys, c = 'red', s=5)  # plot points 
plt.show()

Полученный график: Изображение 174551

В качестве альтернативы можно использовать бесчисленное вещание и сократить код:

import matplotlib.pyplot as plt
import numpy as np

fig=plt.figure(figsize=(8, 8))

n_dots = 120   # set number of dots
angs = np.linspace(0, 2*np.pi, n_dots)  # angles to the dots
cx, cy = (50, 20)  # center of circle
ra = 20.0          # radius of circle

# with numpy broadcasting feature...
# no need to do loop computation as in above version
xs = cx + ra*np.cos(angs)
ys = cy + ra*np.sin(angs)

plt.scatter(xs, ys, c = 'red', s=5)  # plot points 
plt.show()

Ещё вопросы

Сообщество Overcoder
Наверх
Меню