gpt4 book ai didi

r - 带有nearPoints()的动态ggplot图层 Shiny

转载 作者:行者123 更新时间:2023-12-02 03:32:49 27 4
gpt4 key购买 nike

我熟悉 Shiny 的基础知识,但在这里遇到了一些困难。我希望能够在单击某个点以突出显示该点时添加 ggplot 图层。我知道 ggvis 可以做到这一点,并且画廊中有一个很好的示例,但我希望能够使用 nearPoints() 来捕获点击作为 ui 输入。

我尝试过一些(见下文),它除了 ggplot 图层之外,还出现然后消失。我已经尝试使用 reactive()eventReactive() 等对此进行各种编辑。

非常感谢任何帮助...

library(shiny)
library(ggplot2)

shinyApp(
ui = shinyUI(
plotOutput("plot", click = "clicked")
),

server = shinyServer(function(input, output) {
output$plot <- renderPlot({
ggplot(mtcars, aes(x = mpg, y = wt)) +
geom_point() +
geom_point(data = nearPoints(mtcars, input$clicked), colour = "red", size = 5)
})
})
)

我想我从概念上理解为什么这不起作用。该图依赖于 input$clicked,这意味着当 input$clicked 更改时,图会重新渲染,但这又会重置 input$clicked >。有点像第 22 条军规的情况。

最佳答案

请尝试这个:

方法 1(推荐)

library(shiny)
library(ggplot2)

# initialize global variable to record selected (clicked) rows
selected_points <- mtcars[0, ]
str(selected_points)


shinyApp(
ui = shinyUI(
plotOutput("plot", click = "clicked")
),

server = shinyServer(function(input, output) {

selected <- reactive({
# add clicked
selected_points <<- rbind(selected_points, nearPoints(mtcars, input$clicked))
# remove _all_ duplicates if any (toggle mode)
# http://stackoverflow.com/a/13763299/3817004
selected_points <<-
selected_points[!(duplicated(selected_points) |
duplicated(selected_points, fromLast = TRUE)), ]
str(selected_points)
return(selected_points)
})

output$plot <- renderPlot({
ggplot(mtcars, aes(x = mpg, y = wt)) +
geom_point() +
geom_point(data = selected(), colour = "red", size = 5)
})
})
)

如果您单击某个点一次,该点就会突出显示。如果您第二次单击它,突出显示将再次关闭(切换)。

代码使用全局变量selected_points来存储实际突出显示(选定)的点,并使用响应式表达式selected(),每当单击一个点时都会更新全局变量.

str(selected_points) 可能有助于可视化工作情况,但可以删除。

方法 2(替代)

有一种稍微不同的方法,它使用 observe() 而不是 reactive() 并直接引用全局变量 selected_points 而不是返回来自函数的对象:

library(shiny)
library(ggplot2)

selected_points <- mtcars[0, ]
str(selected_points)


shinyApp(
ui = shinyUI(
plotOutput("plot", click = "clicked")
),

server = shinyServer(function(input, output) {

observe({
# add clicked
selected_points <<- rbind(selected_points, nearPoints(mtcars, input$clicked))
# remove _all_ duplicates (toggle)
# http://stackoverflow.com/a/13763299/3817004
selected_points <<-
selected_points[!(duplicated(selected_points) |
duplicated(selected_points, fromLast = TRUE)), ]
str(selected_points)
})

output$plot <- renderPlot({
# next statement is required for reactivity
input$clicked
ggplot(mtcars, aes(x = mpg, y = wt)) +
geom_point() +
geom_point(data = selected_points, colour = "red", size = 5)
})
})
)

当然,您可以直接在ggplot调用中使用全局变量selected_points,而不是调用 react 函数selected()。但是,您必须确保每当 input$clicked 更改时都会执行 renderPlot()。因此,对 input$clicked 的虚拟引用必须包含在 renderPlot() 内的代码中。

现在,响应式(Reactive)函数 selected() 不再需要,可以用 observe() 表达式代替。与 reactive() 不同,observe() 不返回值。每当 input$clicked 被修改时,它只会更新全局变量 selected_points

方法 3(无功值)

这种方法避免了全局变量。相反,它使用 reactiveValues 创建一个类似列表的对象 rv,具有响应式编程的特殊功能(请参阅 ?reactiveValues)。

library(shiny)
library(ggplot2)

shinyApp(
ui = shinyUI(
plotOutput("plot", click = "clicked")
),

server = shinyServer(function(input, output) {

rv <- reactiveValues(selected_points = mtcars[0, ])

observe({
# add clicked
rv$selected_points <- rbind(isolate(rv$selected_points),
nearPoints(mtcars, input$clicked))
# remove _all_ duplicates (toggle)
# http://stackoverflow.com/a/13763299/3817004
rv$selected_points <- isolate(
rv$selected_points[!(duplicated(rv$selected_points) |
duplicated(rv$selected_points, fromLast = TRUE)), ])
str(rv$selected_points)
})

output$plot <- renderPlot({
ggplot(mtcars, aes(x = mpg, y = wt)) +
geom_point() +
geom_point(data = rv$selected_points, colour = "red", size = 5)
})
})
)

请注意,在observer部分中对rv的引用需要封装在isolate()中,以确保只有对input$clicked 将触发observer中代码的执行。否则,我们将陷入无限循环。每当 react 值 rv 发生更改时,就会触发 renderPlot 的执行。

结论

就我个人而言,我更喜欢使用 react 函数的方法 1,这使得依赖关系( react 性)更加明确。我发现方法 2 中对 input$clicked 的虚拟调用不太直观。方法 3 需要彻底了解 react 性并在正确的位置使用 isolate()

关于r - 带有nearPoints()的动态ggplot图层 Shiny ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40805513/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com