【问题标题】:Is it possible in R to hide plotly subplots using a dropdown是否可以在 R 中使用下拉菜单隐藏情节子图
【发布时间】:2022-08-20 03:55:37
【问题描述】:

我正在尝试根据data.frame 中的一个组生成一系列小的plotly 图,然后使用plotly::subplot() 将它们绑定在一起。然后我想使用dropdown 过滤器只显示一些子图。

到目前为止(使用 plotly 文档https://plotly.com/r/map-subplots-and-small-multiples/ 和这个答案https://stackoverflow.com/a/66205810/1498485)我可以创建图和按钮,并显示和隐藏子图的内容。

但我无法弄清楚如何隐藏/重置轴,因此只显示选定的子图。下面是我正在做的一个最小化的例子。

# create data 
df <- expand.grid(group = LETTERS[1:4],
                  type = factor(c(\'high\',\'med\',\'low\'), levels = c(\'high\',\'med\',\'low\')),
                  date = seq(as.Date(\'2020-01-01\'), Sys.Date(), \'month\')) %>%
  mutate(value = abs(rnorm(nrow(.)))) %>%
  group_by(group)

# define plot function
create_plots <- function(dat){
  legend <- unique(dat$group) == \'A\'
  plot_ly(dat, x = ~date) |> 
  add_lines(y = ~value, color = ~type, legendgroup = ~type, showlegend = legend) %>%
  add_annotations(
    text = ~unique(group),
    x = 0.1,
    y = 0.9,
    yref = \"paper\",
    xref = \"paper\",
    xanchor = \"middle\",
    yanchor = \"top\",
    showarrow = FALSE,
    font = list(size = 15)
  )
}

# create buttons to filter by group (based on https://stackoverflow.com/a/66205810/1498485)
buttons <- LETTERS[1:4] |> 
  lapply(function(x){
    list(label = x,
         method = \'update\',
         args = list(list(
           name = c(\'high\', \'med\', \'low\'), 
           visible = unlist(Map(rep, x == LETTERS[1:4], each = 3))
             )))
  })

# generate subplots
df %>%
  do(mafig = create_plots(.)) %>%
  subplot(nrows = 2) %>%
  layout(
    updatemenus = list(
      list(y = 0.8,
           buttons = buttons))
    )

    标签: r plotly interactive subplot r-plotly


    【解决方案1】:

    是的,但据我所知,你必须超越 Plotly 包。此解决方案使用库 htmltoolsshinyRPG。 (这不是一个闪亮的应用程序!)

    我不认为shinyRPG 是一个 cran 包。 (不是在我获得它的时候。)要下载这个包,请使用这个。

    devtools::install_github("RinteRface/shinyRPG")
    

    我正在使用这个库来制作选择框。我没有使用下拉菜单,而是使用了多个选择框(您可以同时选择一个到多个图)。

    我做的第一件事是注释掉绘图的布局选项并将它们分配给一个对象。

    # generate subplots
    so <- df %>%
      do(mafig = create_plots(.)) %>%
      subplot(nrows = 2) #%>%
      # layout(
      #   updatemenus = list(
      #     list(y = 0.8,
      #          buttons = buttons))
      # )
    

    我对原始子图对象所做的唯一其他更改是更改默认高度。我使用这个百分比是因为选择框有 15% 的空间(宽度方向)。

    so[["sizingPolicy"]][["defaultHeight"]] <- "80%"
    

    接下来是选择框。

    在选项方面,我有 c(setNames(1:4, LETTERS[1:4])) 这在选择选项中反映为 A、B、C 和 D,因为您在图表上已标记。您可以将其更改为任何内容。匹配的名称与将选择连接到绘图无关。但是,1:4 的值可以。如果更改此设置,将影响选择成功。

    tagSel <- rpgSelect(
      "selectBox",
      "Selections:",
      c(setNames(1:4, LETTERS[1:4])), # left is values, right is labels
      multiple = T)
    tagSel$attribs$class <- 'select'
    tagSel$children[[2]]$attribs$class <- "mutli-select"
    tagSel$children[[2]]$attribs$onchange <- "getOps(this)"
    

    使用browsable,我将选择框、Javascript 和将选择与绘图可见性、一些样式选项和子绘图连接起来的 JQuery 组合在一起。

    如果看起来很多,其实绝大多数都是为了美化。 (那是几乎style 标签中的所有内容。)

    我在 JS 中添加了很多彗星,但如果有不清楚的地方,请告诉我。

    browsable(tagList(list(
      tags$head(
        tags$script(HTML("function getOps(sel) { /* activate select */
                $plts = $('svg g.cartesianlayer').find('g.subplot'); /* find plots */
                $labs = $('svg g.infolayer').find('g.annotation');   /* find plot labels */
                $plts.addClass('plotter');               /* add opacity to plots */
                $labs.addClass('plotter');               /* add opacity to subplot labels */
                for(i = 0; i < sel.length; i++) { /* look through options */
                  opt = sel.options[i];
                  j = opt.value;
                  if ( opt.selected ) {
                    $plts.filter(':nth-child(' + j + ')').removeClass('plotter-inact');
                    $labs[i].firstChild.classList.remove('plotter-inact');
                  } else {
                    $plts.filter(':nth-child(' + j + ')').addClass('plotter-inact');
                    $labs[i].firstChild.classList.add('plotter-inact');
                  }
                }
              }")),
        tags$style(".plotter {opacity: 1;}
                   .plotter-inact {opacity: 0;}
                   .select { 
                     position: relative; width: 13ch;
                     border: 2px solid #003b70;
                     margin: 0 2px; cursor: pointer;
                     border-radius: 5px; font-size: 1.1em;
                     text-align: center; line-height: 1.25em;
                   }
                   #selectBox {
                     background-color: #003b70;
                     width: 10ch; text-align: center;
                     color: white; font-weight: bold;
                     line-height: 1.25em;
                   }
                   .yaLeft {
                    position: relative;
                    float: left; width: 85%;
                    height: 100vh;
                   }
                   .yaRight {
                     float: right; width: 15%;
                   }")),
      div(div(class = "yaLeft", so), 
          div(class = "yaRight", tagSel)))))
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-02-28
      • 1970-01-01
      • 2020-10-30
      • 1970-01-01
      • 2018-08-18
      相关资源
      最近更新 更多