Reputation: 698
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
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