如何使用 ggplot 将点随机散布在圆圈内,而不围绕中心聚集?

How to randomly scatter points inside a circle with ggplot, without clustering around the center?

我想用ggplot画一个圆,然后在里面散点。我有代码 () 可以让我非常接近我想要的。但是,我希望这些点 随机 散布在圆圈内,但现在我在中心周围得到了一个不需要的簇。

我看到了 ,但它是用 c# 编写的,我不明白如何使其适应 R 代码。

到目前为止我的代码

下面的代码定义了一个自定义的可视化函数vis_points_inside_circle(),然后调用了4次,给出了4个用我现在的方法可视化的例子

library(ggplot2)
library(ggforce)

## set up function
vis_points_inside_circle <- function(n) {
  
  # part 1 -- set up empty circle
  df_empty_circle <-
    data.frame(x = 0,
               y = 0, 
               r = 1)
  
  p_empty_circle <-
    ggplot(df_empty_circle) +
    geom_circle(aes(x0 = x, y0 = y, r = r)) + 
    coord_fixed() +
    theme_void()
  
  # part 2 -- set up points scatter
  r <- runif(n)
  th <- runif(n)
  
  df_circular_points_scatter <- 
    data.frame(x = r*cos(2*pi*th),  ## from @Ben's answer: 
               y = r*sin(2*pi*th))
  
  
  # part 3 -- combine circle and points
  p_empty_circle +
    geom_point(data = df_circular_points_scatter, 
               aes(x = x, y = y))
}

## visualize
library(gridExtra)

set.seed(2021)
p1000_1 <- vis_points_inside_circle(n = 1000)
p1000_2 <- vis_points_inside_circle(n = 1000)
p2000_1 <- vis_points_inside_circle(n = 2000)
p2000_2 <- vis_points_inside_circle(n = 2000)


gridExtra::grid.arrange(p1000_1, p1000_2, p2000_1, p2000_2, nrow = 2)

reprex package (v2.0.0)

创建于 2021-08-02

应该很容易注意到每个圆圈中心周围的集群。怎样才能在圆圈内随机排列点,避免在圆心出现集群?

我尝试 sample()

我想解决方案涉及修改 df_circular_points_scatter 数据。但是,我不知道如何。我试图用 sample() 包裹 df_circular_points_scatter 的每一列,但后来得到的点超出了圆周,总体上呈“交叉”排列。

也就是说,如果我们像这样用 sample() 换行:

r  <- runif(n)
th <- runif(n)

df_circular_points_scatter <- 
    data.frame(x = sample(r*cos(2*pi*th)),  
               y = sample(r*sin(2*pi*th)))

则结果为:


知道如何避免集群吗?我不一定想要完全均匀的散布。圈内随意。


期望的输出

取自 ,所需的输出应如下所示:

您的点最终分布在 r 和 theta 中,但您希望它们均匀分布在区域

因为圆圈中的面积元素是 $r dr dtheta$(不是你的代码暗示的 $dr dtheta$),所以你应该变换 r <- sqrt(r)

你快到了。采样需要按如下方式进行:

r <- runif(n)
th <- runif(n, 0, 2 * pi)
  
df_circular_points_scatter <- 
 data.frame(x = sqrt(r) * cos(th), 
            y = sqrt(r) * sin(th)

)

(参见 this 关于交叉验证的问题)

结果: