Is it possible to plot arrows in plotly in such a format as geom_gene_arrow from gggenes?

59 Views Asked by At

I would love to incorporate arrow shapes in plotly plots to represent genes as is possible with gggenes geom_gene_arrow, that is, thick arrows that can preferably overlap bars. Is this possible?

enter image description here

https://cran.r-project.org/web/packages/gggenes/vignettes/introduction-to-gggenes.html

1

There are 1 best solutions below

0
On BEST ANSWER

An obvious way round this is to make the arrows yourself as polygons. The following function will handle the geometry:

make_arrows <- function(start, stop, yvals, groups, head_length = 500,
                        body_width = 0.1, head_width = 0.15) {
  
  dfs <- Map(function(start, stop, yval, group, arrow_num) {
    if(stop - start > head_length) {
    x <- c(start, start, stop - head_length, stop - head_length, stop,
           stop - head_length, stop - head_length, start, start)
    y <- c(yval, yval + body_width/2, yval + body_width/2, yval + head_width/2,
           yval, yval - head_width/2, yval - body_width/2, yval- body_width/2,
           yval)
    } else {
      x <- c(start, start, stop, start, start)
      y <- c(yval, yval + head_width/2, yval, yval - head_width/2, yval)
    }
    data.frame(x = x, y = y, arrow_num = arrow_num, group = group)
  }, start = start, stop = stop, yval = yvals, 
  group = groups, arrow_num = seq_along(start))
  do.call(rbind, dfs)
}

Then, suppose you have data like this:

df <- data.frame(start = c(15200, 17000, 18000, 18400, 19000, 22300, 22400,
                           23500, 25000),
                 stop = c(17000, 18000, 18400, 19000, 22300, 22400, 
                          23500, 25000, 27000),
                 Gene = LETTERS[1:9])

Then you can plot it as follows:

library(ggplot2)

p <- ggplot(make_arrows(df$start, df$stop, 1, df$Gene), aes(x, y, fill = group)) +
  geom_polygon(color = "black") +
  scale_y_continuous(NULL, limits = c(0.7, 1.3), 
                     breaks = 1, labels = "Genome1") +
  labs(x = NULL, y = NULL) +
  scale_fill_manual(values = c("#8cd2c6", "#fdfcb3", "#bdb9da", "#fa7f72",
                               "#7fb0d2", "#fbb361", "#feea6e", "#bb7ebd",
                               "#cceac3"), guide = "none") +
  facet_wrap(.~"Genome1") +
  theme_gray(base_size = 20) +
  theme(legend.position = "none")

p

enter image description here

And you get a nice result in plotly:

plotly::ggplotly(p)

enter image description here