You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在R的Plotly分组柱状图中添加按钮切换X轴数据

问题描述

我想用Plotly创建分组柱状图,展示每位艺人的T恤销量及类型,同时添加按钮实现单个艺人数据的切换查看,但初始代码无法正常运行。调整数据结构后,新问题是:选择下拉菜单中的艺人时,希望只展示该艺人有销量的产品(动态移除0值),请问是否可行?


初始数据与代码

数据框

artists <- c("Black Waitress", "Black Pumas")
tee_x<- c(20, 0)
tee_y <- c(3, 18)
tee_z <- c (30,0)
tee_t <- c(0,35)
data2 <- data.frame(artists, tee_x, tee_y,tee_t)

尝试的初始代码

fig <- plot_ly(data=data2, x = ~artists, y = ~tee_x, type = 'bar', name = 'tee_x')
fig <- fig %>% add_trace(y = ~tee_y, name = 'tee_y')
fig <- fig %>% add_trace(y = ~tee_t, name = 'tee_t')
fig <- fig %>% layout(yaxis = list(title = 'Count'), barmode = 'group',
                      updatemenus = list(
                          list(
                            y = 0.8,
                            buttons = list(
                              list(method = "restyle",
                                   args = list("x", list(data2[c(1),(2:4)])),
                                   label = "Black Waitress"),

                              list(method = "restyle",
                                   args = list("x", list(data2[c(2),(2:4)])),
                                   label = "Black Pumas")))
                            ))

fig

补充尝试的数据与代码

调整后的数据框

product <- c("tee_X","tee_y","tee_t")
artists <- c("Black Waitress", "Black Pumas")
Black_Waitress<- c(20, 0, 0)
Black_Pumas <- c(3, 18, 0)
tee_z <- c (30,0)
tee_t <- c(0,35)
data2 <- data.frame(product, Black_Waitress, Black_Pumas)

补充代码

show_vec = c()

for (i in 1:length(artists)){
  show_vec = c(show_vec,FALSE)
}
get_menu_list <- function(artists){
  n_names = length(artists)
  buttons = vector("list",n_names)
  
  for(i in seq_along(buttons)){
    show_vec[i] = TRUE
    buttons[i] = list(list(method = "restyle",
                           args = list("visible", show_vec),
                           label = artists[i]))
    print(list(show_vec))
    show_vec[i] = FALSE
  }
  
  return_list = list(
    list(
      type = 'dropdown',
      active = 0,
      buttons = buttons
    )
  )
  
  return(return_list)
}
print(get_menu_list(artists)) 
fig <- plot_ly(data=data2, x = ~product, y = ~Black_Waitress, type = 'bar')
fig <- fig %>% add_trace(y = ~Black_Pumas)
fig <- fig %>% layout(showlegend = F,yaxis = list(title = 'Count'), barmode = 'group',
                      updatemenus = get_menu_list(artists))
fig

解决方案

完全可以实现切换艺人时只显示非0销量的产品,核心是通过长格式数据整理+独立trace控制+动态更新x轴来实现。以下是完整可运行的代码:

library(plotly)
library(tidyr)

# 1. 整理为长格式数据(过滤掉0销量记录)
product <- c("tee_x","tee_y","tee_t")
Black_Waitress <- c(20, 0, 0)
Black_Pumas <- c(3, 18, 35) # 修正原数据中tee_t的数值,匹配初始数据
data_long <- data.frame(product, Black_Waitress, Black_Pumas) %>%
  pivot_longer(cols = -product, names_to = "artist", values_to = "sales") %>%
  filter(sales > 0)

# 2. 为每个艺人创建独立的trace
fig <- plot_ly()
# 添加Black Waitress的trace(默认显示)
fig <- fig %>% add_trace(
  data = data_long %>% filter(artist == "Black_Waitress"),
  x = ~product, y = ~sales, type = "bar", name = "Black Waitress",
  visible = TRUE
)
# 添加Black Pumas的trace(默认隐藏)
fig <- fig %>% add_trace(
  data = data_long %>% filter(artist == "Black_Pumas"),
  x = ~product, y = ~sales, type = "bar", name = "Black Pumas",
  visible = FALSE
)

# 3. 定义下拉菜单按钮:同时控制trace可见性和x轴内容
updatemenus <- list(
  list(
    type = "dropdown",
    active = 0,
    buttons = list(
      list(
        label = "Black Waitress",
        method = "restyle",
        args = list(
          "visible", list(TRUE, FALSE),
          "x", list(data_long %>% filter(artist == "Black_Waitress") %>% pull(product))
        )
      ),
      list(
        label = "Black Pumas",
        method = "restyle",
        args = list(
          "visible", list(FALSE, TRUE),
          "x", list(data_long %>% filter(artist == "Black_Pumas") %>% pull(product))
        )
      )
    )
  )
)

# 4. 布局设置
fig <- fig %>% layout(
  yaxis = list(title = "Count"),
  updatemenus = updatemenus,
  showlegend = FALSE
)

fig

关键细节说明

  • 长格式数据:用pivot_longer将宽格式转为长格式,再过滤掉0销量记录,方便按艺人筛选有效数据
  • 独立trace:每个艺人对应一个独立的trace,通过visible参数控制显示/隐藏
  • 动态x轴:在按钮的args中同时指定x轴的产品列表,确保切换艺人时x轴只显示该艺人有销量的产品
  • 数据修正:原补充代码中Black_Pumas的tee_t数值为0,和初始数据的35不符,已修正保证数据一致性

如果需要保留所有产品的x轴(仅隐藏0销量的柱子),可以基于宽格式数据为每个产品-艺人组合创建trace,再通过按钮控制对应艺人的所有trace显示。

内容的提问来源于stack exchange,提问作者Fras

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.19 12:10:33