How to plot a line with color vector in R Plotly

798 views Asked by At

Say I have the following data frame:

ret <- rnorm(100, 0, 5)
df <- data.frame(
  x = seq(1, 100, 1),
  ret = ret,
  y = 100 + cumsum(ret),
  col = c(ifelse(ret > 0, "red", "forestgreen"), NA)[-1]
)

Here I'm simulating the returns of some fictional financial asset using rnorm named 'ret', and am defining a color vector named 'col' where upticks are green and downticks are red.

What I want to produce is something like the following:

library(ggplot2)
ggplot(df, aes(x=x, y=y)) + geom_line(aes(colour=col, group=1)) 

enter image description here

But I want to make a similar image using plotly so that I can zoom in on sections of the plot. My first thought was to try simply using the ggplotly() function around the code that produced the desired image:

library(plotly)
ggplotly(ggplot(df, aes(x=x, y=y)) + geom_line(aes(colour=col, group=1)))

Using ggplotly

But the plot is no longer grouped. Additionally, I tried using plot_ly() but can't seem to make the line segments get their color according to the 'col' attribute that I'm specifying:

plot_ly(data=df, x = ~x) %>% add_lines(y = ~y, line = list(color=~col))

enter image description here

But my color argument doesn't affect the color of the line. I've tried various other things but keep ending up with one of the two undesired plots. Any help would be much appreciated!

Note: I've already made candlestick and OHLC charts with plot_ly(), but I can't work with them because the y axis doesn't scale when you zoom in to a subsection of the plot.

1

There are 1 answers

0
Marius On BEST ANSWER

I was able to get the desired behaviour from ggplotly by using geom_segment and making each segment link up to the next (x, y) value, regardless of colour:

library(dplyr)
df = df %>%
    arrange(x) %>%
    mutate(x_next = lead(x), y_next = lead(y))

p = ggplot(df, aes(x=x, y=y)) + 
    geom_segment(aes(xend = x_next, yend = y_next, colour=col))
ggplotly(p)

That said, I don't have a good answer for why ggplotly doesn't produce the desired output in the first place.