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

如何在R Markdown中用Plotly为柱状图添加2019-2024年份下拉筛选菜单?

问题:为Plotly交互式柱状图添加年份筛选下拉菜单

我正在使用R Markdown和Plotly制作交互式柱状图,已完成基础图表制作,但无法添加包含2019至2024年的下拉菜单来按年份筛选图表数据。当前使用的代码如下:

dadosbr <- data.frame(
  TIPO_DE_RESISTENCIA = sample(c("Primária", "Adquirida", "Ignorado"), 7525, replace = TRUE),
  Regiao = sample(c("Centro-Oeste", "Nordeste", "Norte", "Sudeste", "Sul"), 7525, replace = TRUE),
  ANO_TRAT = sample(2019:2024, 7525, replace = TRUE),
  UF = sample(c("Acre", "Alagoas", "Amapá", "Amazonas", "Bahia", "Ceará", "Distrito Federal", "Espírito Santo", "Goiás", "Maranhão", "Mato Grosso", "Mato Grosso do Sul",
                "Minas Gerais", "Pará", "Paraíba", "Paraná", "Pernambuco", "Piauí", "Rio de Janeiro", "Rio Grande do Norte", "Rio Grande do Sul", "Rondônia", "Roraima",
                "Santa Catarina", "São Paulo", "Sergipe", "Tocantins"), 7525, replace = TRUE))

graf9 <- dadosbr %>%
  group_by(ANO_TRAT, Regiao, TIPO_DE_RESISTENCIA, UF) %>%
  tally() %>%
  mutate(TIPO_DE_RESISTENCIA = factor(TIPO_DE_RESISTENCIA, levels = c("Primária", "Adquirida", "Ignorado")))

# Convert ggplot object to plotly
graf9_plotly <- ggplot(graf9, aes(x = UF, y= n, fill = TIPO_DE_RESISTENCIA)) +
  geom_bar(position = "fill", stat = "identity") +
  labs(x = "UF de residência", 
       y = "% casos TBDR",
       fill = "Tipo de resistência")+ 
  scale_fill_brewer(palette = "Set1", direction = 1) +
  theme_classic() + 
  scale_y_continuous(labels = scales::percent, expand = expansion(mult = c(0, .1))) +
  facet_grid(. ~ Regiao , scales = "free", space = "free") +
  theme(axis.text.x = element_text(angle = 90, hjust = 1, vjust = 0.5)) +
  theme(
    legend.position = "right",
    axis.line = element_line(colour = "black"),
    axis.text.x = element_text(colour = "black"),
    axis.text.y = element_text(colour = "black"),
    plot.caption = element_text(hjust = 0.5, vjust = 1, margin = margin(t = 10), size = 10),
    plot.title = element_text(hjust = 0.5, vjust = 1, margin = margin(t = 10), size = 12)
  )

# Convert ggplot to plotly
graf9_plotly <- ggplotly(graf9_plotly)

# Display the plotly object
graf9_plotly
解决方案

直接通过ggplotly()转换的图表难以自定义添加下拉菜单,推荐使用Plotly原生语法构建图表并集成筛选控件,具体实现如下:

library(plotly)
library(dplyr)
library(scales)

# 数据预处理(保持原逻辑)
dadosbr <- data.frame(
  TIPO_DE_RESISTENCIA = sample(c("Primária", "Adquirida", "Ignorado"), 7525, replace = TRUE),
  Regiao = sample(c("Centro-Oeste", "Nordeste", "Norte", "Sudeste", "Sul"), 7525, replace = TRUE),
  ANO_TRAT = sample(2019:2024, 7525, replace = TRUE),
  UF = sample(c("Acre", "Alagoas", "Amapá", "Amazonas", "Bahia", "Ceará", "Distrito Federal", "Espírito Santo", "Goiás", "Maranhão", "Mato Grosso", "Mato Grosso do Sul",
                "Minas Gerais", "Pará", "Paraíba", "Paraná", "Pernambuco", "Piauí", "Rio de Janeiro", "Rio Grande do Norte", "Rio Grande do Sul", "Rondônia", "Roraima",
                "Santa Catarina", "São Paulo", "Sergipe", "Tocantins"), 7525, replace = TRUE))

graf9 <- dadosbr %>%
  group_by(ANO_TRAT, Regiao, TIPO_DE_RESISTENCIA, UF) %>%
  tally() %>%
  mutate(
    TIPO_DE_RESISTENCIA = factor(TIPO_DE_RESISTENCIA, levels = c("Primária", "Adquirida", "Ignorado")),
    # 计算百分比(对应position="fill"的逻辑)
    pct = n / sum(n),
    # 为分面准备分组
    facet_group = Regiao
  ) %>%
  ungroup()

# 定义年份列表
years <- unique(graf9$ANO_TRAT)
years <- sort(years)

# 初始化Plotly图表
p <- plot_ly()

# 为每个年份添加对应的trace
for (y in years) {
  year_data <- graf9 %>% filter(ANO_TRAT == y)
  # 为每种抗性类型添加trace
  for (res in levels(year_data$TIPO_DE_RESISTENCIA)) {
    res_data <- year_data %>% filter(TIPO_DE_RESISTENCIA == res)
    p <- p %>%
      add_bars(
        data = res_data,
        x = ~UF,
        y = ~pct,
        color = ~TIPO_DE_RESISTENCIA,
        colors = "Set1",
        name = res,
        # 初始只显示2021年的数据
        visible = (y == 2021),
        # 指定分面分组
        facet = ~facet_group
      )
  }
}

# 定义下拉菜单按钮
dropdown_buttons <- lapply(years, function(y) {
  # 构建visible数组:当前年份的所有trace设为TRUE,其他为FALSE
  visible <- unlist(lapply(years, function(yr) {
    rep(yr == y, length(levels(graf9$TIPO_DE_RESISTENCIA)))
  }))
  list(
    method = "restyle",
    args = list("visible", visible),
    label = as.character(y)
  )
})

# 添加默认的"全部年份"按钮(可选)
dropdown_buttons <- c(
  list(
    method = "restyle",
    args = list("visible", rep(TRUE, length(years)*length(levels(graf9$TIPO_DE_RESISTENCIA)))),
    label = "Todos os anos"
  ),
  dropdown_buttons
)

# 配置图表布局
p <- p %>%
  layout(
    updatemenus = list(
      list(
        type = "dropdown",
        active = 1, # 默认选中2021年(对应buttons列表的第2个元素)
        buttons = dropdown_buttons,
        x = 0.1,
        y = 1.15
      )
    ),
    yaxis = list(
      title = "% casos TBDR",
      tickformat = ".0%",
      range = c(0, 1.1)
    ),
    xaxis = list(
      title = "UF de residência",
      tickangle = -90
    ),
    legend = list(
      title = list(text = "Tipo de resistência"),
      orientation = "v",
      x = 1.05,
      y = 0.5
    ),
    margin = list(l = 50, r = 150, t = 70, b = 150)
  ) %>%
  config(displayModeBar = TRUE)

# 显示图表
p

关键说明

  1. 数据预处理:新增pct字段模拟ggplot中position="fill"的百分比计算逻辑
  2. Trace创建:为每个年份的每种抗性类型单独创建trace,通过visible参数控制初始显示状态
  3. 下拉菜单配置:每个按钮对应一组visible数组,通过restyle方法切换不同年份的trace显示
  4. 样式对齐:保持Y轴百分比格式、X轴标签角度、颜色方案与原ggplot图表一致

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.21 13:55:56