gdkrmr
gdkrmr

Reputation: 698

Interactively change color of points in traces in R plotly

I want to create an interactive plotly 3d scatter with markers and lines in R. The graphic should be able to highlight individual traces, which is working. It should also be able to change the color according to other variables.

Here is an example of what I want to do, the highlighting works fine, changing the color does not work:

library(plotly)
irs <- data.table(iris)
setkey(irs, `Species`)
p <- plot_ly(type = "scatter3d", mode = "lines+markers")
for (i in levels(irs$Species)) {
  xx <- irs[i]$Sepal.Length
  yy <- irs[i]$Sepal.Width
  zz <- irs[i]$Petal.Length
  cc <- irs[i]$Petal.Width
  p <- p %>% add_trace(x = xx, y = yy, z = zz, color = cc)
}
p <- p %>%
  layout(
    updatemenus = list(
      ## set opacity per trace to highlight a single trace
      list(y = 0.6,
           buttons = lapply(
             levels(irs$Species),
             function (x) {
               list(method = "restyle",
                    args = list("opacity",
                                ifelse(levels(irs$Species) == x,
                                       1, 0.1)),
                    label = x)
             })),
      ##  try to set different colors for points inside traces
      ## NOT WORKING
      list(y = 0.4,
           buttons = lapply(
             names(irs),
             function(x) {
               list(
                 method = "restyle",
                 args = list(
                   "color",
                   split(irs[[x]], irs$Species)
                 ),
                 label = x
               )
             }))
    )
  )
p

Upvotes: 0

Views: 1412

Answers (1)

Marco Sandri
Marco Sandri

Reputation: 24262

The following code solves only a small part of your problem: how to change colors of markers and lines for a single series.
I did not find a solution for the case with multiple series.
In addition, I did not find a way for an automatic rescaling of the color map after changing the color variable from the menu. Hence, I rescaled "by hand" all variables between 1 and 3.
I realise that this is a small contribution to the solution of the problem. Anyway, I hope it can help you.

library(plotly)

library(scales)
irs <- iris
irs[,1:4] <- apply(irs[,1:4],2, rescale, to=c(1,3))

p <- plot_ly(data = irs, type = "scatter3d", mode = "lines+markers")
p <- p %>% add_trace(x=~Sepal.Length, y=~Sepal.Width, 
                  z=~Petal.Length, color=~Petal.Width)

p <- p %>%
  layout(
    updatemenus = list(
      list(y = 0.4,
           buttons = lapply(
             names(irs),
             function(x) {
               cols <- as.numeric(irs[,x])
               list(
                 method = "restyle",
                 label = x,
                 args = list(
                  list(marker.color=list(cols),
                       line.color=list(cols), autocolorscale=TRUE)
                 )
               )
             }))
    )
  )
p

Upvotes: 2

Related Questions