如何在Shiny中实现可点击直方图,点击柱子即可获取对应数据框行名
这个需求可以实现,核心通过Shiny内置的绘图点击事件捕获+分箱区间匹配完成,以下是完整可运行代码和核心逻辑说明:
library(shiny) library(ggplot2) library(dplyr) ui <- fluidPage( titlePanel("可点击直方图"), sidebarLayout( sidebarPanel(), mainPanel( # 给plotOutput添加click参数绑定点击事件 plotOutput("hist", click = "hist_click"), hr(), h4("点击柱子对应行名:"), verbatimTextOutput("selected_rows") ) ) ) # 预处理数据,保留行名 mtcars_hp <- mtcars %>% select(hp) %>% # 把行名存成一列方便后续筛选 tibble::rownames_to_column("car_name") # 提前固定直方图参数,和绘图时保持一致,保证bin计算规则统一 bin_num <- 10 hp_range <- range(mtcars_hp$hp) bin_width <- diff(hp_range)/bin_num bin_breaks <- seq(hp_range[1], hp_range[2], length.out = bin_num + 1) server <- function(input, output) { output$hist <- renderPlot({ ggplot(mtcars_hp, aes(x = hp)) + geom_histogram(bins = bin_num, fill = "red", col = "black", alpha = 0.4) + labs(x = "values", y = "Frequency", title = "Histogram") + scale_x_continuous(breaks = pretty(mtcars_hp$hp, n = 10)) }) # 监听点击事件,返回对应行名 output$selected_rows <- renderPrint({ req(input$hist_click) # 获取点击的x坐标值 click_x <- input$hist_click$x # 找到点击位置对应的bin区间 bin_idx <- findInterval(click_x, bin_breaks, rightmost.closed = TRUE) bin_min <- bin_breaks[bin_idx] bin_max <- bin_breaks[bin_idx + 1] # 筛选该bin内的所有行名 selected_cars <- mtcars_hp %>% filter(hp >= bin_min, hp < bin_max | (bin_idx == bin_num & hp == bin_max)) %>% pull(car_name) selected_cars }) } shinyApp(ui = ui, server = server)
核心逻辑说明
- 给
plotOutput添加click参数绑定点击事件的输入名,用户点击绘图区域时,坐标数据会自动存入对应的input变量中 - 提前固定直方图的分箱参数(分箱数量、上下限、分箱断点),保证绘图用的分箱规则和后续匹配点击位置用的规则完全一致,避免匹配偏差
- 监听点击事件,获取点击位置的x坐标,通过
findInterval匹配对应的分箱区间,再筛选出hp落在该区间内的所有行的行名返回
内容的提问来源于stack exchange,提问作者emr2
相关产品推荐
相关产品推荐

