Spiral barplot using ggplot & coord_polar (Condegram)

旧城冷巷雨未停 提交于 2019-11-30 02:43:58

问题


I'd like to create a bar plot on an Archimedean spiral, like discussed here.

With an end goal of something like this, but less overwhelming.

Here's a sample dataframe:

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

I can make a bar graph, using the following code:

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

And I can make the spiral, using the following code:

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

But how (if at all) can I plot the bars on the spiral?

This is about as close as I've gotten: creating a spiral with my data rather than the above formula. But my data isn't actually displayed...

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

回答1:


A fun question. To do this properly with bars, we need to use polygons to correctly account for the 'warp' of each corner. This plot will look better the more bars per cycle you have, but you can change the y limits to avoid strong distortion in the center. You'll have to come up with some way to nicely label the y-axis, but coord_polar isn't very good at that to begin with.

library(tidyverse)

First, either create sample df from scratch:

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) 

Or, working from an existing df:

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

Continue with the following:

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

An alternative is to just make a spiralling heatmap:

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



来源:https://stackoverflow.com/questions/41603341/spiral-barplot-using-ggplot-coord-polar-condegram

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!