通过绘图下拉菜单切换显示的轨迹 [英] Switch displayed traces via plotly dropdown menu

查看:19
本文介绍了通过绘图下拉菜单切换显示的轨迹的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用 R 编程语言.我正在尝试在此处为我自己的数据复制本教程:

现在我要做的是让用户切换"(切换)这些图表(如这里所示:

一些相关信息:https://plotly.com/r/custom-buttons/https://plotly.com/r/multiple-axes/

I am working with the R programming language. I am trying to replicate this tutorial over here for my own data: https://plotly.com/r/dropdowns/

I created some fake data and made 4 plots:

#load libraries 

library(plotly)
library(MASS)
library(dplyr)


# create data

x <- sample( LETTERS[1:4], 731, replace=TRUE, prob=c(0.25, 0.25, 0.25, 0.25) )
y <- rnorm(731,10,10)
z <- rnorm(731,5,5)
date= seq(as.Date("2014/1/1"), as.Date("2016/1/1"),by="day")
    
    df <- data.frame(x,y, z, date)
df$x = as.factor(df$x)



# plot 1 : time series

 aggregate = df %>%
        mutate(date = as.Date(date)) %>%
        group_by(month = format(date, "%Y-%m")) %>%
        summarise( mean = mean(y))

ts_1 <- ggplot(aggregate) + geom_line(aes(x = month, y = mean, group = 1)) +  theme(axis.text.x = element_text(angle = 90)) + ggtitle("time series 1")

plot_1 = ggplotly(ts_1)



#plot 2 : box plot

plot_2 <- plot_ly(df, y = ~y, color = ~x, type = "box") %>% layout(title = "boxplot")



#plot 3, 4 : scatter plots

df_1 <- df[which(df$x == "A"),]
df_2 <- df[which(df$x == "B"),]


plot_3 <- plot_ly( data = df_1, type = "scatter", mode = "markers", x = ~ y, y = ~z) %>% layout(title = "graph 3")

plot_4 <- plot_ly( data = df_2, type = "scatter", mode = "markers", x = ~ y, y = ~z) %>% layout(title = "graph 4")

Once these 4 plots have been created, I know how to save them together:

sub = subplot(plot_1, plot_2, plot_3, plot_4, nrows = 2)
#view result
sub

Now what I am trying to do, is have the user "toggle" (switch) between these graphs (as seen here: https://plotly.com/r/dropdowns/)

In a previous post (R: Switching Between Graphs ), I learned how to "glue" similar graphs together (e.g. 4 scatter plots). Now, I am trying to do so with different graphs (2 scatter plots, 1 time series and 1 box plot). I tried to adapt the code from the previous post to suit my example:

fig <- df %>% 
  add_trace(name = "A", plot_1) %>% 
  add_trace (name = "B" , df, y = ~y, color = ~x, type = "box") %>% layout(title = "boxplot")
  add_trace (name = "C" , data = df_1, type = "scatter", mode = "markers", x = ~ y, y = ~z) %>% layout(title = "graph 3") %>%
  add_trace( name = "D", data = df_2, type = "scatter", mode = "markers", x = ~ y, y = ~z) %>% layout(title = "graph 4") %>% 
  layout(xaxis = list(domain = c(0.1, 1)),
         yaxis = list(title = "y"),
         updatemenus = list(
           list(
             y = 0.7,
             buttons = list(
               list(method = "restyle",
                    args = list("visible", list(TRUE, FALSE, FALSE, FALSE)),
                    label = "A"),
               list(method = "restyle",
                    args = list("visible", list(FALSE, TRUE, FALSE, FALSE)),
                    label = "B"),
               list(method = "restyle",
                    args = list("visible", list(FALSE, FALSE, TRUE, FALSE)),
                    label = "C"),
               list(method = "restyle",
                    args = list("visible", list(FALSE, FALSE, FALSE, TRUE)),
                    label = "D")))))

But this produces the following errors:

Error: $ operator is invalid for atomic vectors
Error in add_data(p, data) : argument "p" is missing, with no default

Can someone please show me if it is possible to fix this problem? Instead of using the "add_trace" approach, is it somehow possible to individually call each plotly graph object by its name (e.g. subplot(plot_1, plot_2, plot_3, plot_4, nrows = 2)), "glue" all the graphs together, and then add a "toggle button" that lets the user switch between them?

(note: I need to be able to save the final result as a "html" file)

Thanks

解决方案

First of all, you should take care about plots which add multiple traces (see nTracesA etc.)

Besides changing the trace visibility you'll need to seperate categorial and numerical data onto separate x and y-axes and manage their visibility, too (see xaxis2, xaxis3, xaxis4 - this also works with a single y-axis but in this case the grid isn't displayed properly)

As described in the docs:

The updatemenu method determines which plotly.js function will be used to modify the chart. There are 4 possible methods:

  • "restyle": modify data or data attributes
  • "relayout": modify layout attributes
  • "update": modify data and layout attributes
  • "animate": start or pause an animation (only available offline)

Accordingly the following, is using the update method (a lot of repition here - needs some cleanup, but I think it's better to understand this way):

# load libraries
library(dplyr)
library(plotly)

# create data
x <- sample(LETTERS[1:4],
            731,
            replace = TRUE,
            prob = c(0.25, 0.25, 0.25, 0.25))
y <- rnorm(731, 10, 10)
z <- rnorm(731, 5, 5)
date <- seq(as.Date("2014/1/1"), as.Date("2016/1/1"), by = "day")

df <- data.frame(x, y, z, date)
df$x = as.factor(df$x)

nTracesA <- nTracesC <- nTracesD <- 1
nTracesB <- length(unique(df$x))

plotA <- plot_ly(data = df %>%
                   mutate(date = as.Date(date)) %>%
                   group_by(month = format(date, "%Y-%m")) %>%
                   summarise(mean = mean(y)),
                 type = 'scatter', mode = 'lines', x= ~ month, y= ~ mean, name = "plotA", visible = TRUE, xaxis = "x", yaxis = "y")

plotAB <- add_trace(plotA, data = df, x = ~x, y = ~y, color = ~ x, name = ~ paste0("plotB_", x), 
                    type = "box", xaxis = "x2", yaxis = "y2", visible = FALSE, inherit = FALSE)

plotABC <- add_trace(plotAB, data = df[which(df$x == "A"),], 
                     type = "scatter", mode = "markers", x = ~ y, y = ~ z, 
                     name = "plotC", xaxis = "x3", yaxis = "y3", visible = FALSE, inherit = FALSE)

plotABCD <- add_trace(plotABC, data = df[which(df$x == "B"),], x = ~ y, y = ~ z,
                      type = "scatter", mode = "markers", name = "plotD", xaxis = "x4", yaxis = "y4", visible = FALSE, inherit = FALSE)

fig <- layout(plotABCD, title = "Initial Title",
              xaxis = list(domain = c(0.1, 1), visible = TRUE, type = "date"),
              xaxis2 = list(overlaying = "x", visible = FALSE),
              xaxis3 = list(overlaying = "x", visible = FALSE), 
              xaxis4 = list(overlaying = "x", visible = FALSE),
              yaxis = list(title = "y"),
              yaxis2 = list(overlaying = "y", visible = FALSE),
              yaxis3 = list(overlaying = "y", visible = FALSE),
              yaxis4 = list(overlaying = "y", visible = FALSE),
              updatemenus = list(
                list(
                  y = 0.7,
                  buttons = list(
                    list(label = "A",
                         method = "update",
                         args = list(list(name = paste0("new_trace_name_", 1:7), visible = unlist(Map(rep, x = c(TRUE, FALSE, FALSE, FALSE), each = c(nTracesA, nTracesB, nTracesC, nTracesD)))),
                                     list(title = "title A",
                                          xaxis = list(visible = TRUE),
                                          xaxis2 = list(overlaying = "x", visible = FALSE),
                                          xaxis3 = list(overlaying = "x", visible = FALSE),
                                          xaxis4 = list(overlaying = "x", visible = FALSE),
                                          yaxis = list(visible = TRUE),
                                          yaxis2 = list(overlaying = "y", visible = FALSE),
                                          yaxis3 = list(overlaying = "y", visible = FALSE),
                                          yaxis4 = list(overlaying = "y", visible = FALSE)))
                    ),
                    list(label = "B",
                         method = "update",
                         args = list(list(visible = unlist(Map(rep, x = c(FALSE, TRUE, FALSE, FALSE), each = c(nTracesA, nTracesB, nTracesC, nTracesD)))),
                                     list(title = "title B",
                                          xaxis = list(visible = FALSE),
                                          xaxis2 = list(overlaying = "x", visible = TRUE),
                                          xaxis3 = list(overlaying = "x", visible = FALSE),
                                          xaxis4 = list(overlaying = "x", visible = FALSE),
                                          yaxis = list(visible = FALSE),
                                          yaxis2 = list(overlaying = "y", visible = TRUE),
                                          yaxis3 = list(overlaying = "y", visible = FALSE),
                                          yaxis4 = list(overlaying = "y", visible = FALSE)))),
                    list(label = "C",
                         method = "update",
                         args = list(list(visible = unlist(Map(rep, x = c(FALSE, FALSE, TRUE, FALSE), each = c(nTracesA, nTracesB, nTracesC, nTracesD)))),
                                     list(title = "title C",
                                          xaxis = list(visible = FALSE),
                                          xaxis2 = list(overlaying = "x", visible = FALSE),
                                          xaxis3 = list(overlaying = "x", visible = TRUE),
                                          xaxis4 = list(overlaying = "x", visible = FALSE),
                                          yaxis = list(visible = FALSE),
                                          yaxis2 = list(overlaying = "y", visible = FALSE),
                                          yaxis3 = list(overlaying = "y", visible = TRUE),
                                          yaxis4 = list(overlaying = "y", visible = FALSE)))),
                    list(label = "D",
                         method = "update",
                         args = list(list(visible = unlist(Map(rep, x = c(FALSE, FALSE, FALSE, TRUE), each = c(nTracesA, nTracesB, nTracesC, nTracesD)))),
                                     list(title = "title D",
                                          xaxis = list(visible = FALSE),
                                          xaxis2 = list(overlaying = "x", visible = FALSE),
                                          xaxis3 = list(overlaying = "x", visible = FALSE),
                                          xaxis4 = list(overlaying = "x", visible = TRUE),
                                          yaxis = list(visible = FALSE),
                                          yaxis2 = list(overlaying = "y", visible = FALSE),
                                          yaxis3 = list(overlaying = "y", visible = FALSE),
                                          yaxis4 = list(overlaying = "y", visible = TRUE))))
                  ))))

print(fig)

# htmlwidgets::saveWidget(partial_bundle(fig), file = "fig.html", selfcontained = TRUE)
# utils::browseURL("fig.html")

Some related info: https://plotly.com/r/custom-buttons/ https://plotly.com/r/multiple-axes/

这篇关于通过绘图下拉菜单切换显示的轨迹的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆