0

I am using hline from ggplot to construct an axis for a data set I am looking out. Essentially I want to selectively color this axis based on a dataframe. This dataframe consists of an array of (7684, 7685,...,7853) and each corresponds to a letter "a", "b", "c", and "d". I would like to correspond each letter with a color used to color that interval on the axis.

For example row 1 of this data frame is: (7684, "c") so I would want to color the interval on the axis from 7684 to 7685 the color of "c" which could be red for instance. I have yet to think of a straightforward solution to this, I am not sure if hline would be the way to go with this.

> df
    p nucleotide 
1   c       7684
2   c       7685
3   t       7686
4   t       7687
5   a       7688
6   c       7689
7   a       7690
8   t       7691
9   a       7692
10  c       7693

Small snippet of what I am talking about. Basically want to associate df$p with colors. And color the interval of the corresponding df$nucleotide

quantik
  • 776
  • 12
  • 26
  • Why not provide a simple [reproducible example](http://stackoverflow.com/questions/5963269/how-to-make-a-great-r-reproducible-example) with sample input data to make it easier to help you. – MrFlick Apr 06 '17 at 19:17
  • `geom_hline(yintercept = vector_here, color = vector_of_colors_here)` What have you tried so far? – Vlo Apr 06 '17 at 19:18
  • I updated the description. I tried something along the lines of wrapping `geom_hline(yintercept = v, colour = df$p[i])` in a forloop indexed on `df$nucleotide[i]` but this did not work as intended. – quantik Apr 06 '17 at 19:29
  • You could try `geom_segment`, using nucleotide for `x` and a lag-1 of nucleotide for the `xend`. That would get rid of the last row of your dataset as it wouldn't have an "end" for the segment – aosmith Apr 06 '17 at 20:55
  • Yeah I am essentially using a forloop like this `for (i in 1:length(df$nucleotide)) { w <- w + geom_segment(aes(x=df$nucleotide[i], y = INTERCEPT, xend=df$nucleotide[i+1], yend = INTERCEPT), size = 2}` But it's only placing the segment for the last value i obtains – quantik Apr 06 '17 at 21:10
  • It's strange because when I move it *all* out of the loop it's functional but it is not writing correctly within the loop – quantik Apr 06 '17 at 21:34

1 Answers1

2

You never use a for loop in ggplot and you should never use df$.. in an aesthetic.

library(dplyr) 
library(ggplot2)

ggplot(df) +
  geom_segment(aes(x = nucleotide, xend = lead(nucleotide), y = 1, yend = 1, color = p), size = 4)
#> Warning: Removed 1 rows containing missing values (geom_segment).

This takes us half the way. What is does is draw a segment from x to xend. x is mapped to the nucleotide value, xend is mapped to lead(nucleotide), meaning the next value. This of course lead to leaving out the last line, as it does not have a next value.

The following code takes care of that, admittedly in a hackish way, adding a row to the df, and then limiting scale_x . It may be not generalizable.

It also add some graphical embellishment.

df %>% 
  add_row(p = '', nucleotide = max(.$nucleotide) + 1) %>% 
  ggplot() +
  geom_segment(aes(x = nucleotide, xend = lead(nucleotide), y = 1, yend = 1, color = p), size = 4) +
  geom_text(aes(x = nucleotide, y = 1, label = nucleotide), nudge_x = .5,  size = 3) +
  scale_x_continuous(breaks = NULL, limits = c(min(df$nucleotide), max(df$nucleotide) + 1)) +
  scale_color_brewer(palette = 'Dark2', limits = c('a', 'c', 't'), direction = 1) +
  theme(aspect.ratio = .2,
        panel.background = element_blank(),
        axis.text.y = element_blank(),
        axis.ticks.y = element_blank(),
        axis.title.y = element_blank())
#> Warning: Removed 1 rows containing missing values (geom_segment).
#> Warning: Removed 1 rows containing missing values (geom_text).

enter image description here

Data

df <- read.table(text = '   p nucleotide 
1   c       7684
2   c       7685
3   t       7686
4   t       7687
5   a       7688
6   c       7689
7   a       7690
8   t       7691
9   a       7692
10  c       7693', header = T)
Community
  • 1
  • 1
GGamba
  • 13,140
  • 3
  • 38
  • 47
  • Thank you! Incredibly well done and exactly what I wanted. The more I was reading I discovered you weren't supposed to use `df$..` with an aesthetic but you can't use a `for` loop with ggplot? A lot of answers on here use that. TIL. Anyway this is great! Thanks again. – quantik Apr 06 '17 at 21:53