【问题标题】:R: Switching Between GraphsR:在图表之间切换
【发布时间】:2021-05-14 10:34:00
【问题描述】:

我正在使用 R 编程语言。我正在尝试按照此处有关“在图表之间切换”的教程进行操作:https://plotly.com/r/dropdowns/(第一个示例)。

首先,我在 R 中生成了一些数据:

library(plotly)
library(MASS)

x <- sample( LETTERS[1:4], 1000, replace=TRUE, prob=c(0.25, 0.25, 0.25, 0.25) )
y <- rnorm(1000,10,10)
z <- rnorm(1000,5,5)
    
    df <- data.frame(x,y, z)
df$x = as.factor(df$x)
    colnames(df) <- c("x", "y", "z")

我尝试修改本教程中的代码以获得最终结果:

fig <- plot_ly(df, x = ~x, y = ~y, z = ~z alpha = 0.3)
fig <- fig %>% add_markers(marker = list(line = list(color = "black", width = 1)))
fig <- fig %>% layout(
    title = "Drop down menus - Plot type",
    xaxis = list(domain = c(0.1, 1)),
    yaxis = list(title = "y"),
    updatemenus = list(
        list(
            y = 0.8,
            buttons = list(
                
                list(method = "restyle",
                     args = list("type", "scatter"),
                     label = "Scatter A"),
                
                list(method = "restyle",
                     args = list("type", "scatter"),
                     label = "Scatter B"),
                
                list(method = "restyle",
                     args = list("type", "scatter"),
                     label = "Scatter C"),
                
                list(method = "restyle",
                     args = list("type", "scatter"),
                     label = "Scatter D")
                
                
            ))

但这似乎不起作用。

相反,我有一个不同的想法:也许我可以创建一系列我希望能够在以下之间“切换”的图表:

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


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

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

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

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

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

现在,是否可以修改 plotly 代码以将所有这些图形(graph_1、graph_2、graph_3、graph_4、graph_5)“绑定”在一起,以便用户可以单击左侧的选项卡并在这些图形之间切换?

谢谢

【问题讨论】:

    标签: r onclick plotly data-visualization interactive


    【解决方案1】:

    您应该查看本教程的示例是最后一个示例(带有正弦波)。它会根据下拉菜单中选择的值隐藏和显示绘图的不同轨迹。

    您只需将数据框的格式更改为宽。

    df.wide <- df %>% tidyr::pivot_wider(names_from = x, values_from=z)
    
    df.wide
    ## A tibble: 1,000 x 5
    #       y     D     B       A     C
    #   <dbl> <dbl> <dbl>   <dbl> <dbl>
    # 1  6.48  6.21 NA    NA      NA   
    # 2 23.6  NA    15.3  NA      NA   
    # 3 -9.99 -2.16 NA    NA      NA   
    # 4 19.6  NA    NA     0.0683 NA   
    # 5 18.8  -1.40 NA    NA      NA   
    # 6 -2.71  9.80 NA    NA      NA   
    # 7  2.32 NA    NA    NA       3.77
    # 8 11.9  NA     4.35 NA      NA   
    # 9 21.4  NA    NA    NA      13.9 
    #10  2.34 NA     2.10 NA      NA   
    ## … with 990 more rows
    

    然后为每一列添加单独的散点跟踪。在下拉菜单的参数中,您可以设置选择每个选项时将显示哪些跟踪。例如args = list("visible", list(TRUE, FALSE, FALSE, FALSE)) 表示只有添加的第一个跟踪(在本例中为列A)将是可见的。

    fig <- plot_ly(df.wide, x = ~y)
    fig <- fig %>% 
      add_trace(y = ~A, name = "A", type='scatter', mode='markers') %>% 
      add_trace(y = ~B, name = "B", type='scatter', mode='markers', visible = F) %>%
      add_trace(y = ~C, name = "C", type='scatter', mode='markers', visible = F) %>%
      add_trace(y = ~D, name = "D", type='scatter', mode='markers', visible = F) %>% 
      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")))))
    

    编辑:还添加箱形图

    为不同类型的图(如箱线图)添加选项有点困难。现在的问题是箱线图中的 x 轴和散点图中的 x 轴是不同的。所以你不能使用相同的轴。幸运的是,plotly 允许您将不同的轨迹映射到不同的轴。然后,您可以使用domain 属性设置这个新轴在完整图中的位置。

    我的解决方案有点hacky,因为我使用domain 属性来“隐藏”我不想使用的“情节”,方法是让它非常小(我还通过设置visible = FALSE 使相应的数据不可见) )。这是因为隐藏轴只会隐藏线条。剧情的背景还剩下你。

    请注意,现在我使用方法update(而不是restyle),因为它还允许您更改绘图的布局(https://plotly.com/r/custom-buttons/)。

    但它似乎工作得很好!

    # I had to reorder the dataframe because the boxplot was not following the order of the factors. Apparently it follows the orders that the letter appear.
    df <- df %>% dplyr::arrange(x)
    
    df.wide <- df %>% tidyr::pivot_wider(names_from = x, values_from=z)
    
    # this is a list with axis config for scatter plot (define here to avoid repetition)
    axis.config.scatter <- list(xaxis = list(title = "x", domain = c(0.1, 1), visible=T),
                                yaxis = list(title = "y", domain = c(0, 1), visible=T),
                                xaxis2 = list(title = "group", domain = c(0.99, 1), visible=F),
                                yaxis2 = list(title = "y", domain = c(0,99, 1), visible=F))
    
    # this is a list with axis config for box plot (define here to avoid repetition)
    axis.config.box <- list(xaxis = list(title = "x", domain = c(0.99, 1), visible=F),
                            yaxis = list(title = "y", domain = c(0.99, 1), visible=F),
                            xaxis2 = list(title = "group", domain = c(0.1, 1), visible=T, anchor='free'),
                            yaxis2 = list(title = "y", domain = c(0, 1), visible=T, anchor='free'))
    
    
    fig <- plot_ly(df.wide)
    fig <- fig %>% 
      add_trace(x = ~y, y = ~A, name = "A", type='scatter', mode='markers') %>% 
      add_trace(x = ~y, y = ~B, name = "B", type='scatter', mode='markers', visible = F) %>%
      add_trace(x = ~y, y = ~C, name = "C", type='scatter', mode='markers', visible = F) %>%
      add_trace(x = ~y, y = ~D, name = "D", type='scatter', mode='markers', visible = F) %>% 
      add_trace(data=df, x=~x, y=~z, name='box', type='box', visible=F, xaxis='x2', yaxis='y2') %>%
      layout(xaxis = list(title = "x", domain = c(0.1, 1)),
             yaxis = list(title = "y"),
             xaxis2 = list(title = "group", domain = c(0.99, 1), visible=F),
             yaxis2 = list(title = "y", domain = c(0.99, 1), visible=F),
             updatemenus = list(
               list(
                 y = 0.7,
                 buttons = list(
                   list(method = "update",
                        args = list(list(visible = c(TRUE, FALSE, FALSE, FALSE, FALSE)),
                                    axis.config.scatter),
                        label = "A"),
                   list(method = "update",
                        args = list(list(visible = c(FALSE, TRUE, FALSE, FALSE, FALSE)),
                                    axis.config.scatter),
                        label = "B"),
                   list(method = "update",
                        args = list(list(visible = c(FALSE, FALSE, TRUE, FALSE, FALSE)),
                                    axis.config.scatter),
                        label = "C"),
                   list(method = "update",
                        args = list(list(visible = c(FALSE, FALSE, FALSE, TRUE, FALSE)),
                                    axis.config.scatter),
                        label = "D"),
                   list(method = "update",
                        args = list(list(visible = c(FALSE, FALSE, FALSE, FALSE, TRUE)),
                                    axis.config.box),
                        label = "box")
                   ))))
    

    【讨论】:

    • 非常感谢您的帮助!我昨天花了一整天试图让这个工作。我唯一想问的是:假设我想在“无花果”中添加一个“箱线图”。像这样: add_trace(y = ~y, name = "E", type='box', mode='markers', visible = F) %>% .... 因为已经使用 pivot_wider 命令重新格式化数据,这还有可能吗?
    • 您的意思是您想要一个比较 A、B、C 和 D 的箱线图?请注意,您可以在每个跟踪中使用不同的数据集。因此,您可以通过在新跟踪中使用设置 data=df(原始数据框)来创建此箱线图。
    • 我试了一下,它不起作用,因为箱线图有一个离散的 x 轴,而散点图有一个连续的 y 轴。并且不允许两种类型的 x 轴“混合”。不知道你能不能做到...如果我能让它工作,我会更新我的答案。
    • 谢谢你所做的一切,我也在尝试这个。 pivot_wider 语句真的有必要吗?过去,我使用过 htmtools::taglist() 之类的方法,或者您在前面的示例中向我展示的 plotly::subplot() 将不同的图“粘合”在一起。我想看看是否有办法在不使用 pivot_wider() 的情况下做到这一点。
    • @Noob:我也用包含箱线图的方式更新了我的答案。没有pivot_wider,可能还有其他方法可以做到这一点(通常有几种方法可以获得类似的结果)。我学到了很多试图回答这个问题!希望这对你有帮助!
    猜你喜欢
    • 2020-03-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-01-26
    • 1970-01-01
    相关资源
    最近更新 更多