发生多项选择时隐藏图例

Plotly legend is hidden when multiple selection happens

我在下面有一个 shiny 应用程序,我在其中显示了一个基于 Metric 选择的折线图。问题是图例不是每次都显示,当我进行 2 次选择时,颜色也会丢失。

## app.R ##
library(shiny)
library(shinydashboard)
library(plotly)
BRAND<-c("CHOKIS","CHOKIS","CHOKIS","CHOKIS","CHOKIS","CHOKIS","LARA CHOCO CHIPS","LARA CHOCO CHIPS","LARA CHOCO CHIPS")
BRAND_COLOR<-c("#8050f0","#8050f0","#8050f0","#8050f0","#8050f0","#8050f0","#f050c0","#f050c0","#f050c0")

x<-c(23,34,56,77,78,34,34,64,76)
y<-c(43,54,76,78,87,98,76,76,56)
x1<-c(23,34,56,75,78,34,34,64,76)
y1<-c(33,54,76,76,87,98,76,76,56)
x2<-c(53,34,56,77,78,34,34,84,76)
y2<-c(63,54,76,78,87,98,76,76,86)
r<-c(58,46,76,76,54,21,69,98,98)

graph1.data<-data.frame(BRAND,BRAND_COLOR,x,y,x1,y1,x2,y2)



ui <- dashboardPage(
  dashboardHeader(),
  dashboardSidebar(
    selectInput("metric","Metric",c('Gross Sales','Gross Profit','Sell Out'),multiple = T,selected = "Sell Out")
  ),
  dashboardBody(
    plotlyOutput("line")
  )
)

server <- function(input, output) {
  brand.colors <- graph1.data$BRAND_COLOR
  names(brand.colors) <- graph1.data$BRAND
  
  output$line<-renderPlotly({
    metric<-input$metric
    
    if(length(metric) == 1) {
      for ( i in 1:length(brand.colors))
      {
        graph1.data$BRAND[i]=paste(graph1.data$BRAND[i],metric)
      }
      if (metric!="Sell Out")
      {
        for (i in 9)
        {
          brand.colors[i]="gray"
          graph1.data$BRAND[i]="Insignificant"
        }
      }
      
      names(brand.colors) <- graph1.data$BRAND

      p <- graph1.data %>%
        ggplot2::ggplot(aes(x, y, color = BRAND))
      p <- p + 
        ggplot2::geom_line(aes(x)) + 
        # warnings suppressed on text property
        suppressWarnings(ggplot2::geom_point(aes(x, y, size = r), show.legend = TRUE)) +
        ggplot2::scale_color_manual(values = brand.colors)
      
    }
    else if(length(metric) == 2) {
      if ((metric[1]=="Sell Out") || (metric[2]=="Sell Out"))
      {
        
        # print(brand.colors)
        for ( i in 1:length(brand.colors))
        {
          graph1.data$BRAND[i]=paste(graph1.data$BRAND[i],metric[2])
        }
        p <- graph1.data %>%
          ggplot2::ggplot()
        for ( i in 1:length(brand.colors))
        {
          brand.colors[i]=paste(graph1.data$BRAND[i],metric[2])
        }
        names(brand.colors) <- graph1.data$BRAND
        p <- p +
          geom_line(aes(x1,y1)) +geom_point(aes(x1,y1))+
          # warnings suppressed on text property
          suppressWarnings(ggplot2::geom_point(aes(x1, y1, size = r), show.legend = TRUE)) +
          scale_color_manual(values = brand.colors,labels=brand.colors)
        for ( i in 1:length(brand.colors))
        {
          graph1.data$BRAND[i]=paste(graph1.data$BRAND[i],metric[1])
        }
        for (i in 9)
        {
          graph1.data$BRAND_COLOR[i]="gray"
          graph1.data$BRAND[i]="Insignificant"
          
        }
        brand.colors1 <- graph1.data$BRAND_COLOR
        names(brand.colors1) <- graph1.data$BRAND
        
        p <- p +
          geom_line(aes(x,y),color=brand.colors1) +geom_point(aes(x,y))+
          suppressWarnings(ggplot2::geom_point(aes(x, y, size = r), show.legend = TRUE))+
          scale_color_manual(values = brand.colors1,labels=brand.colors1)
        
        
      }
      else if ((metric[1]!="Sell Out") && (metric[2]!="Sell Out"))
      {
        p <- graph1.data %>%
          ggplot2::ggplot()
        
        for ( i in 1:length(brand.colors))
        {
          names(brand.colors)[i]=paste(graph1.data$BRAND[i],metric[2])
        }
        for (i in 9)
        {
          brand.colors[i]="gray"
          graph1.data$BRAND[i]="Insignificant"
        }
        brand.colors<-graph1.data$BRAND_COLOR
        names(brand.colors) <- graph1.data$BRAND
        
        p <- p +geom_point(aes(x,y),color=brand.colors)+
          geom_line(aes(x,y),color=brand.colors) +
          # warnings suppressed on text property
          suppressWarnings(ggplot2::geom_point(aes(x, y, size = r), show.legend = TRUE)) +
          ggplot2::scale_color_manual(values = brand.colors,labels=brand.colors)
        
        
        for ( i in 1:length(brand.colors))
        {
          graph1.data$BRAND[i]=paste(graph1.data$BRAND[i],metric[1])
        }
        
        p<-p+geom_point(aes(x1,y1),color=brand.colors)+
          geom_line(aes(x=x1, y=y1),color=brand.colors)+
          suppressWarnings(ggplot2::geom_point(aes(x1, y1, size = r), show.legend = TRUE))+
          ggplot2::scale_color_manual(values = brand.colors,labels=graph1.data$BRAND)
      }
    }
    else if(length(metric) == 3) {
      p <- graph1.data %>%
        ggplot2::ggplot(aes(x=x2, y=y2,color=BRAND))
      p<- p+
        geom_line(aes(x2)) +
        suppressWarnings(ggplot2::geom_point(aes(x2, y2, size = r), show.legend = TRUE))+
        
        for (i in 9){
          
          brand.colors[i]="gray"
          graph1.data$BRAND[i]="Insignificant"
          
        }
      
      brand.colors1<-graph1.data$BRAND_COLOR
      names(brand.colors1) <- graph1.data$BRAND
      p<- p+
        geom_line(aes(x1,y1)) +
        suppressWarnings(ggplot2::geom_point(aes(x1, y1, size = r), show.legend = TRUE))+
        ggplot2::scale_color_manual(values = brand.colors1)
      p <- p +
        geom_line(aes(x,y)) +
        # warnings suppressed on text property
        suppressWarnings(ggplot2::geom_point(aes(x, y, size = r), show.legend = TRUE))+
        ggplot2::scale_color_manual(values = brand.colors1)
      
    }
    
    
  })
  
}



shinyApp(ui, server)

metric = 2 时您的代码过于复杂。我已经修好了。您可能需要稍微修改一下,因为我不确定您将使用 BRAND1 列做什么。

server <- function(input, output) {
  brand.colors <- graph1.data$BRAND_COLOR
  names(brand.colors) <- graph1.data$BRAND
  
  output$line<-renderPlotly({
    metric<-input$metric
    
    if(length(metric) == 1) {
      for ( i in 1:length(brand.colors))
      {
        graph1.data$BRAND[i]=paste(graph1.data$BRAND[i],metric)
      }
      #print(graph1.data$BRAND)
      if (metric!="Sell Out"){
        brand.colors <- c(rep("gray",length(graph1.data$BRAND)))
        graph1.data$BRAND = c("Insignificant")
        # for (i in 9){  ### this statement does not work; you can make it work by using local() inside for{} or lapply()
        #   brand.colors[i]="gray"
        #   graph1.data$BRAND[i]="Insignificant"
        # }
      }
      
      names(brand.colors) <- graph1.data$BRAND
      
      p <- graph1.data %>% ggplot2::ggplot(aes(x, y, color = BRAND))
      p <- p + 
        ggplot2::geom_line(aes(x)) + 
        # warnings suppressed on text property
        suppressWarnings(ggplot2::geom_point(aes(x, y, size = r), show.legend = TRUE)) +
        ggplot2::scale_color_manual(values = brand.colors)
      
    }else if(length(metric) == 2) {
      for ( i in 1:length(brand.colors)) {
        graph1.data$BRAND[i]=paste(graph1.data$BRAND[i],metric[2])
        graph1.data$BRAND1[i]=paste(graph1.data$BRAND[i],metric[1])  ## not sure what this is for
      }
      names(brand.colors) <- graph1.data$BRAND
      
      if ((metric[1]=="Sell Out") || (metric[2]=="Sell Out")) {
 
        p <- graph1.data %>%  ggplot2::ggplot(aes(x1, y1, color = BRAND)) +
          geom_line() + geom_point()+
          # warnings suppressed on text property
          suppressWarnings(ggplot2::geom_point(aes(x1, y1, size = r), show.legend = TRUE)) +
          scale_color_manual(values = brand.colors,labels=brand.colors)
        
        p <- p +
          geom_line(aes(x,y),color=brand.colors) + geom_point()+
          suppressWarnings(ggplot2::geom_point(aes(x, y, size = r), show.legend = TRUE)) #+
          # scale_color_manual(values = brand.colors,labels=brand.colors)
        
      } else { # if ((metric[1]!="Sell Out") && (metric[2]!="Sell Out"))
        
        p <- graph1.data %>%  ggplot2::ggplot(aes(x,y,color=BRAND)) +
          geom_line() + geom_point() +  
          # warnings suppressed on text property
          suppressWarnings(ggplot2::geom_point(aes(x, y, size = r), show.legend = TRUE))  +
          ggplot2::scale_color_manual(values = brand.colors,labels=brand.colors)
        
        p <- p + geom_line(aes(x1, y1),color=brand.colors) + geom_point() +
          suppressWarnings(ggplot2::geom_point(aes(x1, y1, size = r), show.legend = TRUE)) #+
          # ggplot2::scale_color_manual(values = brand.colors,labels=brand.colors)
      }
    } else if(length(metric) == 3) {
      p <- graph1.data %>%
        ggplot2::ggplot(aes(x=x2, y=y2,color=BRAND))
      p<- p+
        geom_line(aes(x2)) +
        suppressWarnings(ggplot2::geom_point(aes(x2, y2, size = r), show.legend = TRUE))
        
        # for (i in 9){
        #   
        #   brand.colors[i]="gray"
        #   graph1.data$BRAND[i]="Insignificant"
        #   
        # }
      
      brand.colors1<-graph1.data$BRAND_COLOR
      names(brand.colors1) <- graph1.data$BRAND
      p<- p+
        geom_line(aes(x1,y1)) +
        suppressWarnings(ggplot2::geom_point(aes(x1, y1, size = r), show.legend = TRUE)) #+
        # ggplot2::scale_color_manual(values = brand.colors1)
      p <- p +
        geom_line(aes(x,y)) +
        # warnings suppressed on text property
        suppressWarnings(ggplot2::geom_point(aes(x, y, size = r), show.legend = TRUE))+
        ggplot2::scale_color_manual(values = brand.colors1)
      
    }
    
  })
  
}