如何在ggplot2中测量多边形的面积?

时间:2017-12-05 00:21:39

标签: r ggplot2 data-visualization area radar-chart

嗨,大家好, 我有一些样本,我想为每个样本绘制一个多边形,以说明数据的形状。我的数据看起来像这样:

01 0.31707317

02 0.12195122

03 0.09756098

04 0.07317073

05 0.07317073

06 0.07317073

07 0.07317073

08 0.07317073

09 0.04878049

10 0.04878049

我可以使用雷达图轻松绘制雷达图,如下所示:radarchart

但我正在尝试测量结果形状的区域,并将其用作数据形状的度量。这是我挣扎的地方。

我试图将结果图保存为矢量并使用那里的点,但看起来我无法将图表传递给矢量。然后我尝试使用rgdal包将我的图形作为shapefile展开并使用那里的坐标:

coorddf <- SpatialPointsDataFrame(radarchart(as.data.frame(ttradar), pcol=rgb(0.2,0.5,0.5) , pfcol=rgb(0.2,0.5,0.5, 0.2))
, data = radarchart(as.data.frame(ttradar), pcol=rgb(0.2,0.5,0.5) , cglcol = "white", pfcol=rgb(0.2,0.5,0.5, 0.2))

writeOGR(coorddf, dsn = '.', layer = 'mypoints', driver = "ESRI Shapefile")

这不是一个好主意,因为我的数据没有可以用作纬度和长点的值。

有什么建议吗?

2 个答案:

答案 0 :(得分:2)

展开@G5W's excellent point

library(dplyr)
library(ggplot2)

df <- structure(
  list(
    V1 = 1:10,
    V2 = c(
      0.31707317,
      0.12195122,
      0.09756098,
      0.07317073,
      0.07317073,
      0.07317073,
      0.07317073,
      0.07317073,
      0.04878049,
      0.04878049
    )
  ),
  .Names = c("V1", "V2"),
  class = "data.frame",
  row.names = c(NA, -10L)) 

您可以使用dplyr::lead

计算从邻居到右边的每个三角形
areas <- df %>% 
  setNames(c("variable", "value")) %>% 
  mutate(nextval = lead(value, default = value[1]),
         angle   = (1/10) * (2*pi),
                   # change 1/n to number of variables
         area    = value*nextval*sin(angle)/2)
   variable      value    nextval     angle         area
1         1 0.31707317 0.12195122 0.6283185 0.0113640813
2         2 0.12195122 0.09756098 0.6283185 0.0034966406
3         3 0.09756098 0.07317073 0.6283185 0.0020979843
4         4 0.07317073 0.07317073 0.6283185 0.0015734881
5         5 0.07317073 0.07317073 0.6283185 0.0015734881
6         6 0.07317073 0.07317073 0.6283185 0.0015734881
7         7 0.07317073 0.07317073 0.6283185 0.0015734881
8         8 0.07317073 0.04878049 0.6283185 0.0010489921
9         9 0.04878049 0.04878049 0.6283185 0.0006993281
10       10 0.04878049 0.31707317 0.6283185 0.0045456327

有几件事:请注意我使用default = value[1]来确保最终导致的NA包围使用第一个值。此外,您需要使用弧度角度,因此只需 1 / n * 2pi。现在我们已经拥有了所有三角形区域,我们可以添加它们:

areas %>% summarise(total = sum(area))
       total
1 0.02954661

这种方法很容易扩展到多个组进行比较。

df <- expand.grid(var = 1:8, grp = c("a", "b")) %>% 
  mutate(value = runif(length(var), 0.25, 1)) %>% 
  group_by(grp) %>% 
  mutate(nextval = lead(value, default = value[1]),
         angle = (1/8)*(2*pi),
         area = value*nextval*sin(angle)/2) %>% 
  mutate(total = sum(area)) 
# A tibble: 16 x 7
# Groups:   grp [2]
     var    grp     value   nextval     angle       area     total
   <int> <fctr>     <dbl>     <dbl>     <dbl>      <dbl>     <dbl>
 1     1      a 0.3101167 0.6831233 0.7853982 0.07489956 0.5689067
 2     2      a 0.6831233 0.4166692 0.7853982 0.10063417 0.5689067
 3     3      a 0.4166692 0.4756976 0.7853982 0.07007730 0.5689067
 4     4      a 0.4756976 0.3426595 0.7853982 0.05763002 0.5689067
 5     5      a 0.3426595 0.3107870 0.7853982 0.03765135 0.5689067
 6     6      a 0.3107870 0.3001208 0.7853982 0.03297721 0.5689067
 7     7      a 0.3001208 0.9039894 0.7853982 0.09592115 0.5689067
 8     8      a 0.9039894 0.3101167 0.7853982 0.09911594 0.5689067
 9     1      b 0.9888119 0.3481213 0.7853982 0.12170243 1.1749789
10     2      b 0.3481213 0.8513316 0.7853982 0.10478143 1.1749789
11     3      b 0.8513316 0.9928401 0.7853982 0.29883611 1.1749789
12     4      b 0.9928401 0.6372992 0.7853982 0.22370605 1.1749789
13     5      b 0.6372992 0.8303906 0.7853982 0.18710303 1.1749789
14     6      b 0.8303906 0.3607232 0.7853982 0.10590379 1.1749789
15     7      b 0.3607232 0.2786354 0.7853982 0.03553575 1.1749789
16     8      b 0.2786354 0.9888119 0.7853982 0.09741033 1.1749789
df %>% 
  ggplot(aes(var, value)) + 
  geom_polygon() +
  geom_text(aes(0,0, label = round(total, 2)), color = "white") +
  facet_grid(~grp) +
  scale_y_continuous("", limits = c(0, 1), expand = c(0,0)) +
  scale_x_continuous("", breaks = 1:8, expand = c(0,0)) +
  theme_minimal() +
  coord_radar()

enter image description here

如果您正在做很多这些,那么值得查看ggradar包:http://www.ggplot2-exts.org/ggradar.html

由于我只是这样做,我使用了Erwan Le Pennec的极坐标修改: http://www.cmap.polytechnique.fr/~lepennec/R/Radar/RadarAndParallelPlots.html

coord_radar <- function (theta = "x", start = 0, direction = 1) 
{
  theta <- match.arg(theta, c("x", "y"))
  r <- if (theta == "x") 
    "y"
  else "x"
  ggproto("CoordRadar", CoordPolar, theta = theta, r = r, start = start, 
          direction = sign(direction),
          is_linear = function(coord) TRUE)
}

答案 1 :(得分:1)

可以分析地解决您的形状区域。 该区域由一堆三角形组成。例如,楔形 在V1和之间V2看起来像这样。

Wedge

这是side-angle-side problem,因此面积为v1 * v2 * sin(pi / 5)/ 2。第二个楔形的面积为v2 * v3 * sin(pi / 5)/ 2。只需将圆圈周围的三角形加起来即可。