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

Shiny中用appendTab()和ggplot绘图:切换面板后图表颜色异常

问题原因与解决方案

问题分析

你遇到的核心问题是:使用appendTab()动态创建面板后,切换回旧面板时图表颜色会变成最后创建面板的颜色。这是因为你在renderPlot中直接引用了响应式变量input$add_tab——每次点击“Adicione um Painel”按钮,input$add_tab的值都会递增,当旧面板的图表重新渲染时(比如切换回面板),它会读取当前最新的input$add_tab值,而非创建该面板时的数值,导致所有图表颜色统一为最后一次创建面板对应的颜色。

解决方法

在创建每个面板的observeEvent内部,将当前的input$add_tab值保存为一个局部变量,让该面板对应的renderPlot使用这个固定不变的局部变量来选择颜色,而不是动态的input$add_tab。

修改后的完整代码

library(shiny)
library(dplyr)
library(stringr)
library(ggplot2)
library(gapminder)

colors_hex <- c("#FF0000", "#00FF00", "#0000FF", "#FFFF00", "#FF00FF")

data <- gapminder::gapminder %>% filter(country == 'Italy')

# Adiciona ruído aleatório aos valores da coluna 'pop'
desvio_maximo = 0.05  # Ajuste conforme necessário para controlar o desvio máximo
noise <- rnorm(n = nrow(data), mean = 0, sd = desvio_maximo * mean(data$pop))
pop_com_ruido <- data$pop + noise

ui <- fluidPage(
  navbarPage(
    "Rodando Modelos Econométricos com seus dados...",
    id = "tabs"
  ),
  actionButton("add_tab", "Adicione um Painel"),
  tableOutput("head"),
  uiOutput("tabs_content")
)

server <- function(input, output, session) {
  observeEvent(input$add_tab, {
    # 保存当前的面板索引为局部变量,避免后续被input$add_tab的新值覆盖
    tab_index <- input$add_tab
    tab_name <- paste("Gráfico e Regressão Modelo ", tab_index)
    
    appendTab(
      inputId = "tabs",
      tabPanel(tab_name,
               actionButton(inputId = str_remove_all(paste0(tab_name,'criar')," "),
                            paste0("Crie o Gráfico")),
               actionButton(inputId = str_remove_all(paste0(tab_name,'mod')," "),
                            paste0("Rode a ",tab_name)),
               plotOutput(paste0("plot", tab_index))
      ),
      select = TRUE
    )
    
    observeEvent(
      input[[str_remove_all(paste0(tab_name,'criar')," ")]],{
        output[[paste0("plot", tab_index)]] <- renderPlot({
          ggplot(data = data,aes(x = year, y = pop)) + 
            geom_line(color = colors_hex[tab_index])
        })
      })
    
    observeEvent(
      input[[str_remove_all(paste0(tab_name,'mod')," ")]],{
        output[[paste0("plot", tab_index)]] <- renderPlot({
          ggplot(data = data,aes(x = year, y = pop)) +
            geom_line(color = colors_hex[tab_index])+
            geom_line(aes(x = year, y = pop_com_ruido),color = 'black',size = 4)
        })
      })
  })
}

shinyApp(ui, server)

关键修改点

  • 在observeEvent(input$add_tab, {...})开头添加了tab_index <- input$add_tab,将当前按钮点击次数固定为局部变量。
  • 后续所有引用input$add_tab的地方(包括生成面板名称、plot输出ID、颜色选择)都替换为tab_index。
  • 修正了geom_line(aes(x = year, pop_com_ruido))中的语法错误,添加了y=(原代码遗漏会导致报错)。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.07 09:05:58