3
$\begingroup$

I would like to create a random data sample to test a clustering algorithm using python. One specific data sample I would like to generate consists of two non-overlapping annuluses (annuli?); however, it's okay if the inner-most annuli is a circle - as in the image below (taken from this question).

example data

I realize that I can sample N values of angles ti such that 0 ≤ ti ≤ 2 pi. Based on some reading online, I think one can generate N samples of circular data by specifying a fixed radius r such that xi = r cos(ti) and yi = r sin(ti). Applying this reasoning to the desired annulus, I am thinking one can repeat the process for variable radii rmin and rmax; however, I am not sure how to proceed from this point. My thinking is to generate n samples of radii ri (where n < N, the annulus cluster is a subset of all the data) such that rmin ≤ ri ≤ rmax; doing so necessarily means the first cluster should be the n points within the the outer-most annulus and the second cluster should be the N-n points within the inner-most annulus/circle.

So my questions are as follows:

1) Is my approach so far reasonable? Are there (dis)advantages to this approach, such as clustering more near centers or borders?

2) If my approach is wrong, why is it wrong and what would be a better approach?

EDIT:

The original post that serves as a potential duplicate actually shows how to sample points within a circle, not an annulus. I am concerned with the case of an annulus.

$\endgroup$
10
  • $\begingroup$ I'm a bit confused. You write of "two non-overlapping disks", but the innermost disk can be a "circle". Circles are one-dimensional. Your actual picture shows an annulus which is concentric with a disk. If this is what you actually want, please edit your post to clarify. Thank you! $\endgroup$ May 5, 2019 at 3:51
  • $\begingroup$ That was bad terminology on my part. I edited the post to reflect that I would like to sample points within an annulus (not a disk). $\endgroup$
    – user223366
    May 5, 2019 at 3:57
  • 2
    $\begingroup$ Your approach will suffer from the problem the poster in the proposed duplicate pointed out, with a higher density near the center than near the outer boundary. This will afflict both the annulus and the disk, but more so the disk. whuber's answer in the proposed duplicate directly gives you the disk part, and by constraining the part where rho is generated, you get the annulus. $\endgroup$ May 5, 2019 at 3:59
  • $\begingroup$ Is my approach of varying the radius between rmin and rmax the proper way to "constrain the part where rho is generated"? $\endgroup$
    – user223366
    May 5, 2019 at 4:01
  • 1
    $\begingroup$ Even you do not care the density, but for simulation, you still need to specify the density distribution. $\endgroup$
    – user158565
    May 5, 2019 at 4:27

1 Answer 1

3
$\begingroup$

Your approach will suffer from the problem the poster in the proposed duplicate pointed out, with a higher density near the center than near the outer boundary. This will afflict both the annulus and the disk, but more so the disk.

whuber's answer in the proposed duplicate directly gives you the disk part, and by constraining the part where rho is generated, you get the annulus. Note that you need to constrain "on the square root scale".

Here is an adoption of whuber's original R code, which should be easy to translate to Python:

outer_radius <- 1
inner_radius <- 0.7
n <- 1e4
rho <- sqrt(runif(n,inner_radius^2,outer_radius^2))
theta <- runif(n, 0, 2*pi)
x <- rho * cos(theta)
y <- rho * sin(theta)
plot(x, y, pch=19, cex=0.6, col="#00000020")

annulus

$\endgroup$