在R Shiny的ggplotly中移除图例颜色美学,仅保留填充
解决方案
针对你遇到的两个问题(隐藏color图例、给整个堆叠条形加边框),以下是具体的修改方案:
核心思路
原代码通过将selected映射到color aes,导致两个问题:一是ggplotly无法识别ggplot的图例隐藏设置,二是每个分段都会出现边框。改用单独绘制整体边框的方式,既解决图例问题,又实现整体边框效果。
修改后的完整代码
library(shiny) library(shinyWidgets) library(tidyverse) library(plotly) set.seed(123) # 固定随机数,保证复现结果一致 dat <- data.frame( location = rep(c("Loc1", "Loc2", "Loc3"), each = 3), category = rep(c("cat1", "cat2", "cat3"), 3), value = runif(9, 20, 50) ) ui <- fluidPage( sidebarLayout( sidebarPanel( pickerInput( inputId = "selected", label = "选择位置:", choices = c("Loc1", "Loc2", "Loc3") ) ), mainPanel( plotlyOutput("outputPlot") ) ) ) server <- function(input, output) { output$outputPlot <- renderPlotly({ # 计算每个位置的总数值,用于确定边框的右边界 dat_total <- dat %>% group_by(location) %>% summarise(total_value = sum(value), .groups = "drop") %>% mutate(is_selected = location == input$selected) p <- dat %>% ggplot( aes( x = value, y = location, fill = category ) ) + geom_bar(stat = "identity") + # 为选中位置添加整体边框 geom_rect( data = dat_total %>% filter(is_selected), aes( xmin = 0, xmax = total_value, ymin = as.numeric(location) - 0.4, ymax = as.numeric(location) + 0.4, fill = NA # 仅保留边框,不填充颜色 ), color = "red", size = 1 ) + scale_fill_manual(values = c("yellow", "white", "blue")) # 转换为ggplotly,此时仅显示fill对应的图例 ggplotly(p) }) } # 运行应用 shinyApp(ui = ui, server = server)
关键改动说明
- 移除color的aes映射:不再将
selected变量绑定到color美学,彻底避免生成多余图例和分段边框 - 用geom_rect绘制整体边框:通过计算每个位置的总数值,为选中位置绘制一个覆盖整个堆叠条的矩形框,实现整体高亮边框效果
- 自动保留fill图例:由于没有多余的美学映射,ggplotly只会展示
fill对应的分类图例,无需额外隐藏操作
备选方案(保留原color映射逻辑)
如果一定要保留原有的color映射方式,可在ggplotly生成后手动隐藏对应图例,但该方法需要手动指定trace索引,灵活性较差:
server <- function(input, output) { output$outputPlot <- renderPlotly({ dat_selected <- dat %>% mutate(selected = ifelse(location == input$selected, 1, 0)) %>% ggplot( aes( x = value, y = location, group = category, fill = category, color = as.factor(selected) ) ) + geom_bar(stat = "identity") + scale_fill_manual(values = c("yellow", "white", "blue")) + scale_color_manual(values = c("white", "red")) ggplotly(dat_selected) %>% # 隐藏color对应的图例(traces索引需根据实际trace数量调整) style(showlegend = FALSE, traces = 4:6) }) }
内容的提问来源于stack exchange,提问作者anorlondo
相关产品推荐
相关产品推荐

