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

标签 r ggplot2 geometry trigonometry polar-coordinates

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

100pointsbw

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

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

michigan


示例#2——怀俄明州
与密歇根州不同,拜登在怀俄明州只获得了26.55%的选票,大约是四分之一的选票。在本例中,我将绘制一条水平弦来划分圆,使得弦下方的圆盘面积为整个圆盘面积的 25%。然后我将该区域中的各个点涂成蓝色。由于我总共有 100 分,所以 25 分代表怀俄明州投票给拜登的 25% 的人。

wyoming


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

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

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

我知道这有点奇怪的可视化效果,但我将感谢您对此提供的任何帮助。


编辑


我找到了对 JavaScript package 的引用这与我所要求的非常相似。

最佳答案

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

确定适当高度的公式取自 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, 0, 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

关于r - 在ggplot中,如何用一条线绘制一个圆/圆盘,该线根据给定的比例和内部的彩色点划分其面积?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/68605609/

相关文章:

math - gnuplot - 在椭球内绘制随机点

java - 圆形点计数器 Java 或圆形进度条

r - "scale"或 "ruler"在 r 中键入绘图

r - ioslides Markdown 演示幻灯片中的全尺寸 Shiny 应用

r - 如何在 R 中隐藏和调用列表的元素?

c++ - VBO 中的自定义三角形,如何渲染

R:回测交易策略。 quantmod 和 R 的初学者

r - 无法将用户定义函数中的参数传递给 ggplot

r - 带有替换的geom_text位置

r - 在箱线图中标记一个点