2017-01-12 62 views
11

我想上的阿基米德螺旋創建柱狀圖,等討論here螺旋使用ggplot&barplot coord_polar(Condegram)

隨着像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') 

但如何(如果有的話),可以繪製條螺旋?

這與我得到的差不多:使用我的數據而不是上述公式創建螺旋。但我的數據實際上並沒有顯示...

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

回答

12

一個有趣的問題。爲了正確地使用小節做到這一點,我們需要使用多邊形來正確解釋每個角落的「扭曲」。這個圖表看起來會越好,每個週期的棒數越多,但是您可以更改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()) 

enter image description here

另一種方法是隻是做一個螺旋式熱圖:

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)))) 

enter image description here

+2

This.is.awesome。 –

+1

這太棒了!接受答案。我修正了提供的示例df,並在代碼中做了一些更改。如果行數超過24行,可能會有更好的方式來保持代碼的靈活性,但是nrow()似乎適用於我。 3個問題:我會如何根據它們的值對條進行着色?改爲填充=值會創建一個看起來像忍者之星的東西。建議?另外,你可以添加代碼來繪製熱圖嗎?最後,我還在研究如何調整這個以每月繪製多個小節,例如每日一個小節的一個小節。想法歡迎! – jesstme

+1

找出如何操縱顏色。仍然希望指導繪製每個月和每年的每日價值。 'ggplot(poly,aes(x,y,group = interaction(month,year)))+ geom_polygon(aes(fill = value,color = year),size = 1)+ coord_polar()' – jesstme