如何使用 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 关于交叉验证的问题)
结果:
我想用ggplot
画一个圆,然后在里面散点。我有代码 (
我看到了 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 关于交叉验证的问题)
结果: