在ggplot中,如何用一条线绘制一个圆/圆盘,根据给定的比例和里面的彩色点划分其面积?

我想使用圆内的点来可视化比例。例如,假设我有 100 个点希望散布(有点随机抖动)在一个圆圈中。

在ggplot中,如何用一条线绘制一个圆/圆盘,根据给定的比例和里面的彩色点划分其面积?

接下来,我想用这张图来表示每个州在 2020 年美国总统大选中投票给拜登/哈里斯的人的比例。

示例 1 -- 密歇根
拜登获得了密歇根州 50.62% 的选票。我将绘制一个将圆分成两半的水平直径,然后将直径下的点涂成蓝色(民主党的颜色)。

在ggplot中,如何用一条线绘制一个圆/圆盘,根据给定的比例和里面的彩色点划分其面积?


示例 2 -- 怀俄明州
与密歇根州不同的是,在怀俄明州,拜登只获得了 26.55% 的选票,大约是选票的四分之一。在这种情况下,我会画一个水平弦来划分圆,这样弦下方的 磁盘 区域是整个磁盘区域的 25%。然后我会将那个区域的各个点涂成蓝色。因为我总共有 100 分,所以 25 分代表怀俄明州 25% 的人投票给拜登。

在ggplot中,如何用一条线绘制一个圆/圆盘,根据给定的比例和里面的彩色点划分其面积?


我的问题:我怎样才能用 ggplot 做到这一点?我研究了这个问题,这里有很多几何学。首先,我所说的那种区域叫做“circular segment”。其次,如果我们知道有关形状的其他一些参数(例如半径长度等),则有许多公式可以计算其面积。请参阅this不错的演示。

然而,我的目标不是解决几何问题,而只是以一种非常具体的方式表示比例:

  1. 画一个圆
  2. 在里面撒 X 个点
  3. 绘制一条(真实的或不可见的)水平线,根据给定的比例划分圆/圆盘区域
  4. 确保点是根据分割排列的。也就是说,如果我们想表示 30%-70% 的分割,那么在分割磁盘的线下有 30% 的点。
  5. 为线下的点着色。

我知道这有点奇特的可视化效果,但如果您对此提供任何帮助,我将不胜感激。


编辑


我发现了一个对 JavaScript package 的引用,它的作用与我的要求非常相似。

chenzhao5001 回答:在ggplot中,如何用一条线绘制一个圆/圆盘,根据给定的比例和里面的彩色点划分其面积?

我为了好玩而尝试了一下。还有很多事情可以做。我同意这不是可视化比例的好方法,但如果它吸引了您的观众......

用于确定适当高度的公式取自 Wikipedia。特别是我们需要公式

a/A = (theta - sin(theta))/(2*pi)
h = 1-cos(theta/2)

其中 a 是线段的面积; A 是圆的整个面积; theta 是定义线段的弧所描述的角度(图片参见维基百科); h 是线段的高度。

寻找高度的机器。

afun <- function(x) (x-sin(x))/(2*pi)
## curve(afun,from=0,to = 2*pi)
find_a <- function(a) {
    uniroot(
        function(x) afun(x) -a,interval=c(0,2*pi))$root
}
find_h <- function(a) {
    1- cos(find_a(a)/2)
}
vfind_h <- Vectorize(find_h)
## find_a(0.5)
## find_h(0.5)
## curve(vfind_h(x),from = 0,to= 1)

设置一个圈子

dd <- data.frame(x=0,y=0,r=1)
library(ggforce)
library(ggplot2); theme_set(theme_void())
gg0 <- ggplot(dd) + geom_circle(aes(x0=x,y0=y,r=r)) + coord_fixed()

完成

props <- c(0.2,0.5,0.3)  ## proportions
n <- 100                 ## number of points to scatter
cprop <- cumsum(props)[-length(props)]
h <- vfind_h(cprop)
set.seed(101)
r <- runif(n)
th <- runif(n,2 * pi)
  
dd <- 
 data.frame(x = sqrt(r) * cos(th),y = sqrt(r) * sin(th))

dd2 <- data.frame(x=r*cos(2*pi*th),y = r*sin(2*pi*th))
dd2$g <- cut(dd2$y,c(1,1-h,-1))
gg0 + geom_point(data=dd2,aes(x,y,colour = g),size=3)

有很多调整可以使这更好(类别的有意义的名称;反转轴顺序以匹配绘图;可能添加分隔部分的线段,或(更多工作)多边形,以便您可以对部分进行着色。

你应该绝对检查这里是否有错误——例如有些地方我可能使用了一组值,我应该使用它们的第一个差异,反之亦然(值与累积总和)。但这应该会让你开始。

circle with points representing proportions

本文链接:https://www.f2er.com/4048.html

大家都在问