You get colour switch behaviour because your ID's dont all exist across all frames/measure points, so plotly gets confused about continuity I guess.
This can be solved by putting every id in every frame.
library(tidyverse)
library(ggplot2)
library(plotly)
id <- c("drill_1", "drill_2", "drill_3", "drill_1", "drill_2", "drill_2", "drill_3", "drill_2", "drill_3", "drill_2", "drill_2", "drill_1", "drill_2", "drill_3", "drill_1", "drill_3")
signal_1 <- c(6663, 5914, 8471, 7474, 5509, 6206, 17174, 4876, 15243, 5256, 5405, 7094, 5166, 12709, 6838, 12597)
signal_2 <- c(3589, 3733, 5597, 4374, 4000, 4083, 7671, 3864, 6438, 3868, 3817, 4583, 3853, 5033, 4427, 5219)
measure.point <- c(0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 5, 6, 6, 6, 8, 8)
df <- data.frame(ID = id,
signal_1 = signal_1,
signal_2 = signal_2,
measure.point = measure.point)
# http://www.cookbook-r.com/Manipulating_data/Filling_in_NAs_with_last_non-NA_value/
fillNAgaps <- function(x, firstBack=FALSE) {
## NA's in a vector or factor are replaced with last non-NA values
## If firstBack is TRUE, it will fill in leading NA's with the first
## non-NA value. If FALSE, it will not change leading NA's.
# If it's a factor, store the level labels and convert to integer
lvls <- NULL
if (is.factor(x)) {
lvls <- levels(x)
x <- as.integer(x)
}
goodIdx <- !is.na(x)
# These are the non-NA values from x only
# Add a leading NA or take the first good value, depending on firstBack
if (firstBack) goodVals <- c(x[goodIdx][1], x[goodIdx])
else goodVals <- c(NA, x[goodIdx])
# Fill the indices of the output vector with the indices pulled from
# these offsets of goodVals. Add 1 to avoid indexing to zero.
fillIdx <- cumsum(goodIdx)+1
x <- goodVals[fillIdx]
# If it was originally a factor, convert it back
if (!is.null(lvls)) {
x <- factor(x, levels=seq_along(lvls), labels=lvls)
}
x
}
df2 <- df %>% arrange(ID,measure.point) %>%
complete(ID,measure.point) %>%
mutate(across(starts_with("signal"),~fillNAgaps(.x, firstBack = TRUE)))
df2 %>%
plot_ly(
x = ~log10(signal_1),
y = ~log10(signal_2),
color = ~ID,
frame = ~measure.point,
text = ~ID,
hoverinfo = "text",
type = 'scatter',
mode = 'markers+text'
) %>%
layout(
xaxis = list(
type = "log"
)
)