【问题标题】:How to wrap around the polar coordinates in ggplot2 with geom_rect?如何用geom_rect环绕ggplot2中的极坐标?
【发布时间】:2018-11-01 21:34:50
【问题描述】:

我无法使用极坐标切断对象的边界。我正在尝试使用显示所有测量角度的标准偏差的边界矩形绘制平均角度。但是,由于圆坐标的性质,我遇到了 sd 超出极坐标限制的麻烦,我无法让它出现。我已经阅读了this similar question,但由于各种原因,我需要将这些数据放在极坐标系中,所以我没有成功地将那个问题的geom_arc_bar 解决方案应用于我的问题。

这是数据的一个子集:

test <- structure(
  list(group = structure(1:4, .Label = c("1", "2", "3", "4"),class = "factor"), 
       mang = c(100.346364791691, 61.6459563812475, -93.4372656495579, -150.308914571739), 
       mdisp = c(22.1760257078993, 16.1971728831951, 13.7224045052927, 16.3229969619169), 
       sd = c(88.7601477929364, 115.305326107927, 89.1303441207914, 75.4004747324955)), 
  row.names = c(NA, -4L),
  class = c("tbl_df", "tbl", "data.frame"), 
  .Names = c("group", "mang", "mdisp", "sd"))

代码:

library(tidyverse)
ggplot(test)+
  geom_rect(aes(xmin = mang - sd, xmax = mang + sd, ymin = 0,ymax = mdisp, fill = group))+
  geom_segment(aes(x = mang, y = 0, xend = mang, yend = mdisp))+
  scale_x_continuous(breaks = c(-90, 0, 90, 180, 270, 360), limits = c(-180, 180))+
  coord_polar(start = 2*pi, direction = -1)+
  facet_grid(~group)+
  ggtitle("polar plots with sd")

这给出了这个图表:

如果我注释掉设置 x 比例 #scale_x_continuous(breaks=c(-90,0,90, 180, 270, 360),limits=c(-180, 180)) 的行,这些矩形将出现在我希望它们出现的位置,如图所示,但比例错误:

如何让比例尺和边界矩形出现在同一个图上?

【问题讨论】:

    标签: r ggplot2 polar-coordinates


    【解决方案1】:

    一种方法是自己计算环绕量并定义单独的矩形。例如:

    test2 <- test %>%
      mutate(xmin = mang - sd,
             xmax = mang + sd) %>%
      mutate(xmin1 = pmax(xmin, -180),
             xmax1 = pmin(xmax, 180),
             xmin2 = ifelse(xmin < -180, 2 * 180 + xmin, -180),
             xmax2 = ifelse(xmax > 180, 2 * -180 + xmax, 180))
    
    > test2
    # A tibble: 4 x 10
      group   mang mdisp    sd   xmin    xmax  xmin1   xmax1 xmin2 xmax2
      <fct>  <dbl> <dbl> <dbl>  <dbl>   <dbl>  <dbl>   <dbl> <dbl> <dbl>
    1 1      100.   22.2  88.8   11.6  189.     11.6  180    -180  -171.
    2 2       61.6  16.2 115.   -53.7  177.    -53.7  177.   -180   180 
    3 3      -93.4  13.7  89.1 -183.    -4.31 -180     -4.31  177.  180 
    4 4     -150.   16.3  75.4 -226.   -74.9  -180    -74.9   134.  180 
    

    剧情:

    ggplot(test2) +
      geom_rect(aes(xmin = xmin1, xmax = xmax1, ymin = 0, ymax = mdisp, fill = group)) +
      geom_rect(aes(xmin = xmin2, xmax = xmax2, ymin = 0, ymax = mdisp, fill = group)) +
      geom_segment(aes(x = mang, y = 0, xend = mang, yend = mdisp)) +
      scale_x_continuous(breaks = seq(-90, 180, 90), limits = c(-180, 180)) +
      coord_polar(start = 2 * pi, direction = -1) +
      facet_grid(~ group)
    

    【讨论】:

    • 这适用于第 1、3 和 4 组,但对于第 2 组,它应该只是 230 度的范围,但在此处显示为一个完整的圆圈。
    • 更新,我结合使用这种方法和以前的方法,通过组合图来组合一个有效的版本。基本上,我用这种方法绘制了第 1、3 和 4 组,而之前的方法绘制了第 2 组。我将在下面给出完整的答案。
    【解决方案2】:

    通过结合我之前的答案和 Z.lin 给出的解决方案,我最终得到了这些图的一个不优雅但准确的版本。可能有更好的方法来做,但是我的实际数据中没有那么多类别,所以像这样手动做是合理的。

    test3<-filter(test2, group!="2") # filter out the one that doesn't work
    
    ggplot(test)+
      geom_rect(aes(xmin = mang - sd, xmax = mang + sd, ymin = 0,ymax = mdisp))+
      geom_rect(data=test3, aes(xmin = xmin1, xmax = xmax1, ymin = 0, ymax = mdisp)) +
      geom_rect(data=test3, aes(xmin = xmin2, xmax = xmax2, ymin = 0, ymax = mdisp)) +
      geom_segment(aes(x = mang, y = 0, xend = mang, yend = mdisp), color=group)+
      scale_x_continuous(breaks = c(-90, 0, 90, 180, 270, 360), limits = c(-180, 180))+
      coord_polar(start = 2*pi, direction = -1)+
      facet_grid(~group)+
      ggtitle("polar plots with sd")
    

    这给了我这个数字,这是我正在寻找的正确矩形

    谢谢。

    【讨论】:

      【解决方案3】:

      一个更通用的解决方案,在不排除组 2 的情况下工作。它是答案 1 的更正版本。可以使用以下函数进行正确的包装。

      wrap_polar_seg <- function(x, w) {
        a1 = x-w/2
        a2 = x+w/2
        u = matrix(nrow=length(x),ncol=5)
        u[,5] = ifelse(a1 < 0, ifelse(a1 > -180 & a2 > -180, 0,1), 
                               ifelse(a2 < 180 & a2 < 180,0,2)) 
        u[,1] = ifelse(u[,5] == 2,a1,     ifelse(u[,5]==1,360+a1,a1))
        u[,2] = ifelse(u[,5] == 2,180,    ifelse(u[,5]==1,180,   a2))
        u[,3] = ifelse(u[,5] == 2,a2-360, ifelse(u[,5]==1,a2,    a1))
        u[,4] = ifelse(u[,5] == 2,-180,   ifelse(u[,5]==1,-180,  a2))
        u
      }  
      
      

      将此代码应用于当前问题

      test3 = test
      k = wrap_polar_seg(test$mang,test$sd*2)
      test3$xmin1 = k[,1]
      test3$xmax1 = k[,2]
      test3$xmin2 = k[,3]
      test3$xmax2 = k[,4]
      
      
      ggplot(test3) +
        geom_rect(aes(xmin = xmin1, xmax = xmax1, ymin = 0, ymax = mdisp), fill = "gray") +
        geom_rect(aes(xmin = xmin2, xmax = xmax2, ymin = 0, ymax = mdisp), fill = "gray") +
        geom_segment(aes(x = mang, y = 0, xend = mang, yend = mdisp,color=group),size=2) +
        scale_x_continuous(breaks = seq(-90, 180, 90), limits = c(-180, 180)) +
        coord_polar(start = 2 * pi, direction = -1) +
        facet_grid(~ group) +
        theme_bw()
      
      
      

      结果是:

      plot resulting from the code

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2012-05-17
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-10-04
        • 1970-01-01
        相关资源
        最近更新 更多