rplotlyvistime

Specify line color in vistime/plotly timeline in R


I have a very simple timeline I've created using the vistime library in R:

library(vistime)
library(plotly)
data <- read.csv(text="event,group,start,end,color,line.color
                       RedBorder,Project,2016-12-22,2016-12-22,#e8a735,#FF0000
                       BlueBorder,Meetings,2012-03-15,2012-03-15,#e8a735,#0000ff
                       BlueBorder,Meetings,2017-01-12,2017-01-12,#e8a735,#0000ff
                       BlueBorder,Meetings,2019-09-12,2019-09-12,#e8a735,#0000ff
                       BlueBorder,Meetings,2018-08-15,2017-08-15,#e8a735,#0000ff
                       RedBorder,Meetings,2017-01-15,2017-01-15,#e8a735,#FF0000")

#Ordering the data, oldest to newest -- this sorts correctly
data <- data[order(data$start),]

p <- vistime(data)
pb <- plotly_build(p)

#The plot's dates are not ordered
pb$x$data[[2]]$x
#Attempting to order the plot's data.  These are the date elements. No luck ordering.
pb[order(pb$x$data[[2]]$x)] 
for (i in 1:length(pb$x$data)) {
  if (pb$x$data[[i]]$mode == "markers") pb$x$data[[i]]$marker$line$color<- data$line.color
}

pb

I'm trying to get the line color to match what is in the line.color column, but as you see, it's not assigning the correct line color to the points. For example, RedBorder should have red outlines, and BlueBorder events should have blue outlines.


Solution

  • This was tricky! It seems you are getting burned by internal sorting of the data (based on time) inside the "built" Plotly object relative to your input data.

    Basically, the data$line.color does not have the right sort order so the colors were not being mapped to the correct markers.

    Simply pre-ordering your data based on Date e.g. order(data$start) fixes the problem. Moves data row 4 to position 3. EDIT: it appears that sort order may be more complicated, so use match to set the order of data after making pb

    Final edit with more complex data: I originally posted edits without your complete update. You need to know what index of pb$x$data contains your marker X-positions. In your first example it was index 2, in your new example it is index 4.

    library(vistime)
    library(plotly)
    data <- read.csv(text="event,group,start,end,color,line.color
                           RedBorder,Project,2016-12-22,2016-12-22,#e8a735,#FF0000
                           BlueBorder,Meetings,2012-03-15,2012-03-15,#e8a735,#0000ff
                           BlueBorder,Meetings,2017-01-12,2017-01-12,#e8a735,#0000ff
                           BlueBorder,Meetings,2019-09-12,2019-09-12,#e8a735,#0000ff
                           BlueBorder,Meetings,2018-08-15,2017-08-15,#e8a735,#0000ff
                           RedBorder,Meetings,2017-01-15,2017-01-15,#e8a735,#FF0000")
    
    
    data <- as.data.frame(data)  
    data$color <- rgb(1,1,1,0)
    
    p <- vistime(data)
    pb <- plotly_build(p)
    
    
    for (i in 1:length(pb$x$data)) {
      if (pb$x$data[[i]]$mode == "markers") {
        data <- data[match(strftime(pb$x$data[[i]]$x, "%Y-%m-%d"), data$start),]
        pb$x$data[[i]]$marker$line$color<- data$line.color
      }
    }
    #> [1] 4
    
    

    updated example plot with more dates