Home > OS >  using a grouping variable and geom_rect
using a grouping variable and geom_rect

Time:09-17

I want to show covered ranges (including overlaps) and (after some failures with stacked bar plots) I chose geom_rect. The following code works well for one type.

library(tidyverse)

# create dummy data
foo <- tibble(start = c(1, 150, 140, 75, 300),
              end = c(150, 180, 170, 160, 400))

ggplot()  
  geom_rect(data = foo, aes(xmin = start, xmax = end, ymin = 0, ymax = 1), fill = "green", linetype = "blank", alpha = 0.3)  
  geom_rect(data = foo, aes(xmin = 1, xmax = max(end), ymin = 0, ymax = 1), fill = NA, colour = "black")  
  scale_y_continuous(name = "", breaks = NULL, limits = c(0, 1))  
  scale_x_continuous(name = "", breaks = NULL)  
  theme_minimal()  
  theme(panel.grid = element_blank())

ggplot geom_rect 1st try

If I add more data (only one more type, but in the original data I do have some more) like below, I can add the data "by hand", i.e. add two lines of code for each type, but I'm looking for a way to do this by grouping, but didn't succeed.

foo <- foo %>%
  mutate(type = "A", .before = 1)
bar <- tibble(type = "B",
              start = c(1, 30, 40, 100, 150, 200, 310),
              end = c(20, 50, 100, 120, 200, 300, 380))
foo <- bind_rows(foo, bar)

ggplot()  
  geom_rect(data = foo %>% filter(type == "A"), aes(xmin = start, xmax = end, ymin = 0, ymax = 1), fill = "green", linetype = "blank", alpha = 0.3)  
  geom_rect(data = foo, aes(xmin = 1, xmax = max(end), ymin = 0, ymax = 1), fill = NA, colour = "black")  
  geom_rect(data = foo %>% filter(type == "B"), aes(xmin = start, xmax = end, ymin = 2, ymax = 3), fill = "green", linetype = "blank", alpha = 0.3)  
  geom_rect(data = foo, aes(xmin = 1, xmax = max(end), ymin = 2, ymax = 3), fill = NA, colour = "black")  
  scale_y_continuous(name = "", breaks = NULL, limits = c(0, 3))  
  scale_x_continuous(name = "", breaks = NULL)  
  geom_text(aes(x = c(0, 0), y = c(0.5, 2.5), label = c("A", "B")), size = 4, hjust = 2)  
  theme_minimal()  
  theme(panel.grid = element_blank())

ggplot geom_rect 2ndt try

So, the graph already looks the way I want, but I'd prefer to get here by using grouping (or any other non-manual way).

Maybe there's also a different geom or method to get this kind of graph?

CodePudding user response:

You can write a small helper function that positions a categorical value in continuous space. Example below.

helper <- function(x) {(match(x, sort(unique(x))) - 1) * 2}

ggplot(foo)  
  geom_rect(
    aes(xmin = start, xmax = end, 
        ymin = helper(type), 
        ymax = helper(type)   1), 
    fill = "green", linetype = "blank", alpha = 0.3
  )  
  geom_rect(
    aes(xmin = min(start), xmax = max(end),
        ymin = helper(type),
        ymax = helper(type)   1),
    fill = NA, colour = "black"
  )  
  scale_y_continuous(name = "", breaks = NULL, limits = c(0, 3))  
  scale_x_continuous(name = "", breaks = NULL)  
  annotate(
    "text", x = c(0, 0), y = c(0.5, 2.5), label = c("A", "B"), 
    size = 4, hjust = 2
  )  
  theme_minimal()  
  theme(panel.grid = element_blank())

  • Related