simulating random points on a circle

simulating circle
library(ggplot2)
set.seed(0879)

Non-random sampling points in a circle

If we make the incorrect assumption that we can use 2 separate \(UNIF(0,1)\) random variables, one for radius(r) and one for angle(theta) and get a random point in the circle, this is what it would actually look like if we simulate it.

r <- runif(100)
theta <- runif(100, 0, 2*pi)
darts <- data.frame(r, theta)
# breaks adapted from https://stackoverflow.com/questions/24590154
ggplot(darts, aes(r,theta)) + geom_point() + coord_polar(theta = "y") + theme_minimal() + 
  scale_y_continuous(breaks=round(seq(0, 1.99*pi, by=pi/4),2), expand=c(0,0), lim=c(0,2*pi))

r <- runif(1000)
theta <- runif(1000, 0, 2*pi)
darts <- data.frame(r, theta)
ggplot(darts, aes(r,theta)) + geom_point() + coord_polar(theta = "y") + theme_minimal() + 
  scale_y_continuous(breaks=round(seq(0, 1.99*pi, by=pi/4),2), expand=c(0,0), lim=c(0,2*pi))

r <- runif(2500)
theta <- runif(2500, 0, 2*pi)
darts <- data.frame(r, theta)
ggplot(darts, aes(r,theta)) + geom_point(alpha=0.4) + coord_polar(theta = "y") + theme_minimal() + 
  scale_y_continuous(breaks=round(seq(0, 1.99*pi, by=pi/4),2), expand=c(0,0), lim=c(0,2*pi))

r <- runif(10000)
theta <- runif(10000, 0, 2*pi)
darts <- data.frame(r, theta)
ggplot(darts, aes(r,theta)) + geom_point(alpha=0.2) + coord_polar(theta = "y") + theme_minimal() + 
  scale_y_continuous(breaks=round(seq(0, 1.99*pi, by=pi/4),2), expand=c(0,0), lim=c(0,2*pi)) 

r <- runif(100000)
theta <- runif(100000, 0, 2*pi)
darts <- data.frame(r, theta)
ggplot(darts, aes(r,theta)) + geom_point(alpha=0.03) + coord_polar(theta = "y") + theme_minimal() + 
  scale_y_continuous(breaks=round(seq(0, 1.99*pi, by=pi/4),2), expand=c(0,0), lim=c(0,2*pi))

In the higher number of simulated points you can really see that there are more points in the middle (less “area”) and fewer in the outer part of the circle (more “area”, same number of points)).

Random sampling in a square

We can just use \(UNIF(0,1)\) for \(X\) and \(Y\) separately and still get a random point in the square.

x <- runif(100)
y <- runif(100)
dartsx <- data.frame(x, y)
ggplot(dartsx, aes(x,y)) + geom_point() + theme_minimal()

x <- runif(1000)
y <- runif(1000)
dartsx <- data.frame(x, y)
ggplot(dartsx, aes(x,y)) + geom_point() + theme_minimal()

x <- runif(10000)
y <- runif(10000)
dartsx <- data.frame(x, y)
ggplot(dartsx, aes(x,y)) + geom_point() + theme_minimal()

x <- runif(100000)
y <- runif(100000)
dartsx <- data.frame(x, y)
ggplot(dartsx, aes(x,y)) + geom_point(alpha=.1) + theme_minimal()

r <- rbeta(100,2,1)
theta <- runif(100, 0, 2*pi)
dartsb <- data.frame(r, theta)

Uniform random sample on a circle

If we use different variables for radius(r) and angle(theta) this time - we’ll use \(Beta(2,1)\) for the radius - we can take into account that the number of points we need to account for goes up as the radius increases (it is not uniform). Last graph is a density plot of the theta values from many simulations to look at what that \(Beta(2,1)\) distribution of theta values looks like.

ggplot(dartsb, aes(r,theta)) + geom_point() + coord_polar(theta = "y") + theme_minimal() + 
  scale_y_continuous(breaks=round(seq(0, 1.99*pi, by=pi/4),2), expand=c(0,0), lim=c(0,2*pi))

r <- rbeta(1000,2,1)
theta <- runif(1000, 0, 2*pi)
dartsb <- data.frame(r, theta)
ggplot(dartsb, aes(r,theta)) + geom_point() + coord_polar(theta = "y") + theme_minimal() + 
  scale_y_continuous(breaks=round(seq(0, 1.99*pi, by=pi/4),2), expand=c(0,0), lim=c(0,2*pi))

r <- rbeta(2500,2,1)
theta <- runif(2500, 0, 2*pi)
dartsb <- data.frame(r, theta)
ggplot(dartsb, aes(r,theta)) + geom_point() + coord_polar(theta = "y") + theme_minimal() + 
  scale_y_continuous(breaks=round(seq(0, 1.99*pi, by=pi/4),2), expand=c(0,0), lim=c(0,2*pi))

r <- rbeta(10000,2,1)
theta <- runif(10000, 0, 2*pi)
dartsb <- data.frame(r, theta)
ggplot(dartsb, aes(r,theta)) + geom_point(alpha=0.3) + coord_polar(theta = "y") + theme_minimal() + 
  scale_y_continuous(breaks=round(seq(0, 1.99*pi, by=pi/4),2), expand=c(0,0), lim=c(0,2*pi))

r <- rbeta(100000,2,1)
theta <- runif(100000, 0, 2*pi)
dartsb <- data.frame(r, theta)
ggplot(dartsb, aes(r,theta)) + geom_point(alpha=.03) + coord_polar(theta = "y") + theme_minimal() + 
  scale_y_continuous(breaks=round(seq(0, 1.99*pi, by=pi/4),2), expand=c(0,0), lim=c(0,2*pi))

ggplot(dartsb, aes(r)) + geom_density()