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

R Shiny应用中实现多选分组图表垂直排列展示

Shiny 分组垂直分图实现方法

当前代码会将多选的分组数据汇总到同一张图表渲染,要实现每个选中分组对应独立图表、垂直依次排布的效果,直接用facet_wrap分面即可实现,不需要混用base绘图体系的par()函数,修改后的可运行代码如下:

library(shiny)
library(ggplot2)
library(dplyr)
library(shinyWidgets)

DF <- data.frame(dose = c("D1", "D2", "D3", "D1", "D2", "D3", "D1", "D2", "D3"),
                 len = c(4.2, 10, 29.5, 5, 7, 15, 20, 50, 40), 
                 by = c("by.1", "by.1","by.1","by.2","by.2","by.2", "by.3", "by.3", "by.3"))

ui <- fluidPage(
  titlePanel("按分组垂直排布图表"),
  sidebarLayout(
    sidebarPanel( width = 2, selectizeInput(inputId = "by", 
                                            label = "选择分组",
                                            choices = c("by.1", "by.2", "by.3"), 
                                            selected = "by.1",
                                            multiple = T,
                                            options = list('plugins' = list('remove_button')))
    ),
    mainPanel(
      # 开启动态高度适配
      plotOutput("distPlot", height = "auto")
    )
  )
)

server <- function(input, output) {
  output$distPlot <- renderPlot({
    mycols <- c("#92d050", "#57d3ff", "#ffc000")
    
    plot_data <- DF %>%
      filter(by %in% input$by) %>%
      # 按分组内部独立排序,避免跨组排序导致条形顺序错乱
      group_by(by) %>%
      arrange(desc(len), .by_group = TRUE) %>%
      mutate(fills = ifelse(row_number() <= length(mycols), mycols, "grey50"))
    
    ggplot(data = plot_data, aes(x = len, y = reorder(dose, len))) +
      geom_col(aes(fill = I(fills)))+
      geom_text(aes(x = len/2, label = glue::glue("{dose} ({len}%)"))) +
      theme_minimal() +
      scale_x_continuous(NULL, expand = c(0,0)) +
      theme(axis.ticks.y = element_blank(), 
            axis.title.y = element_blank(),
            # 调整分面标题样式适配整体主题
            strip.text = element_text(face = "bold", size = 12),
            strip.background = element_rect(fill = "#f0f0f0", color = NA)) +
      # 核心配置:设置1列布局实现垂直排布
      facet_wrap(vars(by), ncol = 1, strip.position = "top")
  }, height = function(){
    # 按选中分组数量动态计算总高度,每个子图分配200px高度避免挤压
    length(input$by)*200
  })
}

shinyApp(ui = ui, server = server)

核心修改点说明

  • 修正数据预处理逻辑:原代码未做分组拆分排序,会导致不同分组的条形顺序错乱,新增group_by(by)保证每个分组内部按len值独立排序
  • 分面配置:添加facet_wrap(vars(by), ncol = 1),强制所有选中分组对应的子图按单列垂直排列,完全匹配预期的上下排布效果
  • 动态高度适配:给plotOutput和renderPlot增加高度计算逻辑,选中分组越多,绘图总高度自动对应增加,避免子图被压缩变形
  • 样式优化:微调分面标题的文字、背景样式,和整体极简主题风格统一

运行后多选分组即可看到每个分组的图表垂直依次排列,和预期的Plot1、Plot2、Plot3上下排布效果完全一致。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.30 05:42:13