Reputation: 45
I want to produce a plot_ly plot where I change the content of the plot using a button. This all works fine if I define colors for the individual traces like here:
Mn <- rnorm(100, 100, 10)
Fe <- rnorm(100, 20000, 1000)
In <- rnorm(100, 5000, 400)
n <- c(1:100)
df <- tibble(n, Mn, Fe, In, )
df <- mutate(df, name=if_else(n < 30, "stage1", if_else(30<n & n<73, "stage2", "stage3")))
p <- plot_ly(df, x= ~n) %>%
add_markers(y = ~Mn, visible = F) %>%
add_markers(y = ~Fe, visible = F) %>%
add_markers(y = ~In, visible = F) %>%
layout(
updatemenus = list(
list(
yanchor = 'auto',
buttons = list(
list(method = "rescale",
args = list("visible", list(T, F,F)),
label = 'Mn'),
list(method = "rescale",
args = list("visible", list(F,T,F)),
label = 'Fe'),
list(method = "rescale",
args = list("visible", list(F,F,T)),
label = 'In')
))))
gives a plot where I can change the traces.
Now I want to add more information to the data, I want to map the names. This works fine as long as I have a static plot like e.g.:
p <- plot_ly(df) %>%
add_markers(x=~n, y = ~Mn, visible = T, color = ~name)
This looks fine.
But, if I add the color argument to the "changing" plot, it does not work at all.
p <- plot_ly(df) %>%
add_markers(x=~n, y = ~Mn, visible = F, color = ~name) %>%
add_markers(x=~n, y = ~Fe, visible = F, color = ~name) %>%
add_markers(x=~n, y = ~In, visible = F, color = ~name) %>%
layout(
updatemenus = list(
list(
yanchor = 'auto',
buttons = list(
list(method = "rescale",
args = list("visible", list(T, F,F)),
label = 'Mn'),
list(method = "rescale",
args = list("visible", list(F,T,F)),
label = 'Fe'),
list(method = "rescale",
args = list("visible", list(F,F,T)),
label = 'In')
))))
now the button changes the stages and not the elements anymore. So something is definitely mixed up here.
Upvotes: 2
Views: 125
Reputation: 3671
Let's try this. Hopefully it works on your R too.
p <- plot_ly(df, x=~n, color = ~as.factor(name)) %>%
add_markers(y = ~Mn) %>%
add_markers(y = ~Fe, visible = F) %>%
add_markers(y = ~In, visible = F) %>%
layout(
updatemenus = list(
list(
yanchor = "auto",
buttons = list(
list(method = "rescale",
args = list("visible", list(T, T, T, F, F, F, F, F, F, T, F, F)),
label = 'Mn'),
list(method = "rescale",
args = list("visible", list(F, F, F, T, T, T, F, F, F, F, T, F)),
label = 'Fe'),
list(method = "rescale",
args = list("visible", list(F, F, F, F, F, F, T, T, T, F, F, T)),
label = 'In')
))))
The trick is in args = list("visible", list(T, F, F))
. You assumed three layers because there are three plots. But each color or stage is also a layer. So actually you have to define 12 layers in the 'visible' argument. Therefore you need args = list("visible", list(T, T, T, F, F, F, F, F, F, T, F, F))
.
The first three layers (T/F) are the three stages in the first plot, the next three layers are the stages in the second plot. And the next three layers are the three stages in the third plot. And at least there are three layers for each plot one.
So args = list("visible", list(T, T, T, F, F, F, F, F, F, T, F, F))
means show the three stages in plot one (T, T, T), don't show the three stages in plot two and three (F, F, F, F, F, F) and show the markers of the first plot but not the second and third plot (T, F, F).
Edit: I just found, you might not have to specify the last three layers for the plots. It's enough if you just specify the nine stages, so you can remove the last three logicals.
Upvotes: 1