The code is as below:
{r, knitr::opts_chunk$set(echo = TRUE)}
library(plotly)
library(tidyverse)
library(magrittr)
#sample data
result_table = structure(list(wave = c(5L, 5L, 5L, 6L, 6L, 6L), term = c(1L,
2L, 3L, 1L, 2L, 3L), estimate = c(3.317, 0.887, 1, 0.828, 0.995,
1), Std.Error = c(1.249, 1.044, 1, 1.04, 1.003, 1), Statistic = c(10.305,
-1.571, 1, -3.297, -0.96, 1), P.Value = c(1, 1.01, 1, 1, 1.05,
1), conf.low = c(2.829, 0.802, 1, 0.749, 0.989, 1), conf.high = c(3.806,
0.973, 1, 0.906, 1, 1)), class = "data.frame", row.names = c(NA,
-6L))
result_table$wave %<>% as.factor
result_table$term %<>% as.factor
gg <- ggplot(result_table, aes(x = wave, y = estimate,group = term)) +
geom_point(aes(color = wave), size = 2) +
geom_errorbar(aes(ymin=conf.low, ymax=conf.high,color = wave),
linewidth=.1) +
geom_hline(yintercept = 0) +
labs(color = "Wave") +
ylab('Estimate') +
xlab('Term') +
theme_classic()
# Create a plotly object from ggplot
p <- ggplotly(gg)
p <- p %>% layout(showlegend = F,
updatemenus = list(
list(
x = 1.5,
y = 0.8,
# yanchor = "bottom",
# xanchor = 'center',
buttons = list(
list(method = "restyle",
args = list("visible", list(TRUE, FALSE, FALSE)),
label = "1"),
list(method = "restyle",
args = list("visible", list(FALSE, TRUE, FALSE)),
label = "2"),
list(method = "restyle",
args = list("visible", list(FALSE, FALSE, TRUE)),
label = "3")
)
)
)
)
p
In the graph, I would like to make the variable term
as a dropdown list, so that I can select the item in term
and update the plot instantly. However, plotly plotted all the item in term
in the same time, what can I do to fix this problem?
I used the code from Add dropdown filter list to ggplot in RMarkdown HTML file WITHOUT using shiny?, why his code could work well but the code of mine could not work well?
Is it because of geom_errorbar?
As already pointed out by @M-- in the comments, plotly
thinks in traces. And to make your filter work requires to have separate for each term
. I tried to get this right using the group
aes but failed. Instead one option to get separate traces would be to add the geom layers separately for each value of term
by filtering the data. To avoid duplicating code I use lapply
. This way the layers or traces are added as groups of 4 traces per term
, i.e. the first four traces are for term=1
and so on. Hence, you also have to account for that when you set the visibility of the traces in updatemenus
:
library(plotly)
gg <- ggplot(result_table, aes(
x = wave,
y = estimate,
color = wave,
group = term
)) +
lapply(levels(result_table$term), \(x) {
list(
geom_point(data = ~ subset(.x, term == x), size = 2),
geom_errorbar(
data = ~ subset(.x, term == x),
aes(ymin = conf.low, ymax = conf.high),
linewidth = .1
)
)
}) +
geom_hline(yintercept = 0) +
labs(color = "Wave") +
ylab("Estimate") +
xlab("Term") +
theme_classic()
# Create a plotly object from ggplot
p <- ggplotly(gg)
library(plotly)
p <- p %>% layout(
showlegend = F,
updatemenus = list(
list(
x = 1.5,
y = 0.8,
buttons = list(
list(
method = "restyle",
args = list(
"visible",
c(rep(TRUE, 4), rep(FALSE, 4), rep(FALSE, 4), TRUE)
),
label = "1"
),
list(
method = "restyle",
args = list(
"visible",
c(rep(FALSE, 4, 4), rep(TRUE, 4), rep(FALSE, 4), TRUE)
),
label = "2"
),
list(
method = "restyle",
args = list(
"visible",
c(rep(FALSE, 4, 4), rep(FALSE, 4), rep(TRUE, 4), TRUE)
),
label = "3"
)
)
)
)
)
p