Home > front end >  Is it possible to create a circular timeline plot with ggplot?
Is it possible to create a circular timeline plot with ggplot?

Time:02-08

Is it possible to use ggplot to produce a pie chart of a year (or some other period of time) with wedges that correspond to periods set apart by specific dates (that could then be modified using the rest of ggplot's usual tools)?

Here's a cludged sketch of what I think I'm trying to do: date_pie

Using the two dates (21 December and 21 March), we could define the purple/blue area to be "winter;" similar things could be done for the other seasons. R already understands dates, so I thought it might be possible for it to plot time periods like this. While this isn't a super-complicated (or even useful) example, I think it could be a useful technique.

CodePudding user response:

We can use geomtextpath to get the circular labels. Let's say we want to plot the seasons, equinoxes and solstices:

library(geomtextpath)

df <- data.frame(date = as.POSIXct(c("2022-03-20 15:33", "2022-06-21 10:13",
                               "2022-09-23 02:03", "2022-12-21 21:47")),
           event = c("Vernal Equinox", "Summer Solstice",
                     "Autumnal Equinox", "Winter Solstice"))

seasons <- data.frame(xmin = c(-Inf, 2/12, 5/12, 8/12, 11/12),
                      xmax = c(2/12, 5/12, 8/12, 11/12, Inf),
                      ymin = 0, ymax = 0.95,
                      season = c("Winter", "Spring", "Summer",
                                 "Autumn", "Winter"))

The plotting code might look something like this:

ggplot()  
  geom_rect(data = seasons,
            aes(xmin = xmin,xmax = xmax, ymin = ymin, ymax = ymax, fill = season),
            alpha = 0.2)  
  geom_textpath(data = data.frame(x = seq(0.5/13, 12.5/13, length = 12), 
                                  y = 1, label = month.name),
                aes(x, y, label = label), size = 6)  
  geom_textpath(data = data.frame(x = c(0.5/12, 3.5/12, 6.5/12, 9.5/12), y = 0.8,
                                  season = c("Winter", "Spring", "Summer", "Autumn")),
                aes(x, y, color = season, label = season), size = 10,
                alpha = 0.5, fontface = 2)  
  geom_hline(yintercept = c(0.95, 1.05))  
  geom_segment(data = data.frame(x = seq(0, 12/13, length = 12),
    xend = seq(0, 12/13, length = 12),
    y = 0.95, yend = 1.05), aes(x, y, xend = xend, yend = yend))  
  geom_textsegment(data = df,  aes(x = lubridate::decimal_date(date) %% 1,
                   xend = lubridate::decimal_date(date) %% 1,
                   y = 0, yend = 0.95, label = event), vjust = -0.2)  
  scale_fill_manual(values = c(Winter = "deepskyblue4",
                               Spring = "yellowgreen",
                               Summer = "gold",
                               Autumn = "brown"))  
  scale_color_manual(values = c(Winter = "deepskyblue4",
                               Spring = "yellowgreen",
                               Summer = "gold",
                               Autumn = "brown"))  
  scale_x_continuous(limits = c(0, 1), expand = c(0, 0))  
  scale_y_continuous(limits = c(0, 1.05))  
  coord_polar()  
  theme_void()  
  theme(legend.position = "none")

enter image description here

  •  Tags:  
  • Related