R Shiny如何基于用户输入动态生成对应高度的柱状图
问题根因
两次代码无法生成柱状图的核心错误:
- 第一次的
renderPlot块仅读取了input$children的数值,没有调用任何绘图函数生成柱状图对象 - 第二次的
renderPlotly块仅赋值、打印输入数值,同样没有编写绘图逻辑,自然无法输出图表
可运行实现代码
以下代码可以直接运行,输入不同子女数量时,柱状图高度会同步对应变化:
library(shiny) library(ggplot2) #define ui ---------------------------- ui <- fluidPage( textInput( inputId = "first_name", label = "What is your first name? "), textOutput( outputId = "name"), selectInput( inputId = "university", label = "Have you gone to university? (answer Yes/No): ", choices = c("Yes", "No"), width = "100%"), numericInput( inputId = "children", label = "How many children do you have? ", value = 0, min = 0, max = NA), radioButtons( inputId = "wall_type", label = "What is the wall material of your shelter? ", choices =c("Timber", "Bricks", "Iron sheets", "Stone")), textAreaInput( inputId = "Livelihood", label = "What has been your major source of livelihood in the past two weeks? ", rows = 5), textOutput( outputId = "livelihood"), column( 6, plotOutput( outputId = "dependants", width = "100%")) ) #define server ---------------------- server <- function(input, output, session){ output$name <- renderText(paste0("Hello ", input$first_name, " today!")) output$livelihood <- renderText(paste0("Looks like your major work is ", input$Livelihood)) output$dependants <- renderPlot({ # 构造绘图所需数据框 plot_df <- data.frame( label = "Reported children count", value = input$children ) # 绘制柱状图 ggplot(plot_df, aes(x = label, y = value)) + geom_col(fill = "#2c7fb8", width = 0.5) + labs(x = NULL, y = "Number of children", title = "Number of children reported by respondent") + ylim(0, 10) + # 固定Y轴范围,避免数值变化时坐标轴缩放干扰高度对比 geom_text(aes(label = value), vjust = -0.3, size = 6) + theme_bw(base_size = 14) }) } #create shiny app ------------------------ shinyApp(ui, server)
关键修改说明
- 删除了无意义的空响应式对象
dep_plot,直接在渲染函数内读取输入值即可,不需要额外嵌套 - 先将用户输入的单个数值转换为ggplot/plotly可识别的数据框格式,不能直接将单个数值传入绘图函数
- 显式调用柱状图绘制逻辑:静态图用
geom_col()实现,柱子高度直接映射输入的子女数量值,输入5时柱子高度会明显高于输入3的情况 - 增加了固定Y轴范围、柱顶数值标注等优化,保证高度对比直观
如果需要交互式plotly版本,只需要做两处替换:
- 将UI中的
plotOutput替换为plotlyOutput - 将server中
output$dependants对应的渲染块替换为以下代码,提前加载plotly包即可:
output$dependants <- renderPlotly({ plot_df <- data.frame( label = "Reported children count", value = input$children ) plot_ly(plot_df, x = ~label, y = ~value, type = "bar", marker = list(color = "#2c7fb8")) %>% layout( title = "Number of children reported by respondent", yaxis = list(title = "Number of children", range = c(0,10)), xaxis = list(title = "") ) })
内容的提问来源于stack exchange,提问作者Samuel Gachuhi
相关产品推荐
相关产品推荐

