【问题标题】:Spiral barplot using ggplot & coord_polar (Condegram)使用 ggplot 和 coord_polar 的螺旋条形图 (Condegram)
【发布时间】:2017-01-12 00:44:30
【问题描述】:

我想在阿基米德螺旋上创建一个条形图,就像讨论过的 here

最终目标类似于this,但不那么压倒性。

这是一个示例数据框:

    test <- structure(list(month = c(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12,
                                     1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12), 
           year = c(2015, 2015, 2015, 2015, 2015, 2015, 2015, 
                    2015, 2015, 2015, 2015, 2015, 2016, 2016, 
                    2016, 2016, 2016, 2016, 2016, 2016, 2016, 
                    2016, 2016, 2016), 
           value = c(49, 34, 35, 34, 50, 35, 48, 50, 44, 38, 42, 
                   43, 33,30, 42, 43, 58, 55, 47, 36, 35, 53, 
                   61, 59)), 
          .Names = c("month", "year", "value"), 
          class = "data.frame", row.names = c(NA, -24L))

我可以使用以下代码制作条形图:

    ggplot(monthly, aes(x = ym, y = value)) +
      geom_bar(stat = "identity") 

我可以使用以下代码制作螺旋:

    a <- 0   #Any number here & it still looks the same to me...
    b <- 10  #Any number here & it still looks the same to me...
    theta <- seq(0,10*pi, 0.01)
    r <- a + b*theta
    df <- data.frame(x = r*cos(theta), y = r*sin(theta))
    ggplot(df, aes(x,y)) + 
      geom_point(col = 'red')

但我如何(如果有的话)在螺旋上绘制条形

这与我得到的差不多:使用 my 数据而不是上述公式创建螺旋。但是我的数据实际上并没有显示出来......

    d <- ggplot(monthly, aes(x = month, y = month, color = year)) + 
      geom_path(size = 2) + 
      coord_polar() +
      theme_minimal() + 
      theme(legend.position = "none")
    d

【问题讨论】:

    标签: r ggplot2 polar-coordinates spiral


    【解决方案1】:

    一个有趣的问题。要正确使用条形图,我们需要使用多边形来正确解释每个角的“扭曲”。每个周期的条越多,该图看起来会更好,但您可以更改 y 限制以避免中心出现严重失真。您必须想出一些方法来很好地标记 y 轴,但 coord_polar 一开始就不太擅长。

    library(tidyverse)
    

    首先,要么从头开始创建示例 df:

    monthly <- 
      expand.grid(month = 1:12, year = factor(unique(monthly$year))) %>% 
      mutate(value = runif(n(), 10, 20),
             y = as.numeric(year) - 1 + (month - 1) / 12) 
    

    或者,使用现有的 df:

        monthly <- monthly %>%
          mutate(y = as.numeric(year) - 1 + (month - 1) / 12)
    

    继续以下操作:

    bars <- monthly %>% 
      mutate(value_norm = value / (max(value) * 1.1),
             xmin = month - 0.5,
             xmax = month + 0.5,
             ymin = y,
             ymax = y + value_norm)
    # we could plot `bars` here, but things will not line up nicely, since
    # the bar will be nice and flat, but it needs to curve with the spiral.
    
    poly <- bars %>% 
      rowwise() %>% 
      do(with(., data_frame(year = year,
                            month = month,
                            x = c(xmin, xmax, xmax, xmin),
                            y = c(ymin - 1/24, 
                                  ymin + 1/24, 
                                  ymax + 1/24, 
                                  ymax - 1/24))))
    
    ggplot(poly, aes(x, y, fill = interaction(month, year))) + 
      geom_polygon(col = 1) +
      coord_polar() +
      ylim(-3, 5) +
      viridis::scale_fill_viridis(discrete = TRUE, option = 'C') +
      scale_x_continuous(breaks = 1:12, labels = month.name) +
      theme_minimal() + 
      theme(legend.position = "none", axis.text.y = element_blank(),
            axis.title = element_blank())
    

    另一种方法是制作一个螺旋形热图:

    bars2 <- monthly %>% 
      mutate(xmin = month - 0.5,
             xmax = month + 0.5,
             ymin = y,
             ymax = y + 1)
    
    poly2 <- bars2 %>% 
      rowwise() %>% 
      do(with(., data_frame(value = value,
                            year = year,
                            month = month,
                            x = c(xmin, xmax, xmax, xmin),
                            y = c(ymin - 1/24, ymin + 1/24, ymax + 1/24, ymax - 1/24))))
    

    【讨论】:

    • 这太棒了!回答接受。我修复了提供的示例 df 并对您的代码进行了一些更改。如果行数超过 24 行,可能有更好的方法来保持代码的灵活性,但 nrow() 似乎对我有用。 3 个问题:我将如何根据它们的值对条形图进行着色?更改为 fill = value 会创建一些看起来像忍者星的东西。建议?另外,你能添加代码来绘制热图吗?最后,我仍在研究如何调整它以每月绘制多个条形图,例如每天绘制一个条形图。欢迎提出想法!
    • 想出了如何操作颜色。仍然希望在每个月和年内绘制每日值的指导。 ggplot(poly, aes(x, y, group = interaction(month, year))) + geom_polygon(aes(fill = value, colour = year), size = 1) + coord_polar()
    • 我知道我没有提供完全灵活的功能,但是应该比较容易适应吧? y = as.numeric(year) - 1 + (month - 1) / 12 将不得不改变,几天之内它将类似于y = as.numeric(year) - 1 + (day - 1) / 365。并且多边形需要通过1/730而不是1/24进行调整。
    • 是的,将分组与填充分开是您实际按值着色的方式。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-08-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多