闪亮:鼠标悬停点处带有垂直线和数据标签的交互式ggplot [英] Shiny: Interactive ggplot with Vertical Line and Data Labels at Mouse Hover Point
问题描述
我想看看是否可以在有光泽的应用程序中创建折线图:
I want to see if I can create a line chart in a Shiny app that:
- 画一条垂直线穿过,并且
- 标签
每个geom_line()
上与鼠标悬停点的x值最接近的数据点,类似于以下两个图表的组合:
the data point closest to the x-value of the mouse hover point on each geom_line()
, something like a combination of these two charts:
这是我第一次尝试使ggplot图形具有交互性.我遇到了一些奇怪的行为,希望有人可以向我解释.我的可复制示例如下.它创建两个系列,并用geom_line()
对其进行绘制.我距离期望的最终状态(如上所述)仅几步之遥,但我的直接问题是:
This is my first attempt at making my ggplot graph interactive. I've run into some strange behavior that I'm hoping someone can explain to me. My reproducible example is below. It creates two series and plots them with geom_line()
. I'm a few steps from my desired endstate (explained above), but my immediate questions are:
- 当鼠标超出绘图范围时,如何摆脱垂直线?我尝试过的所有操作(例如,如果
input$plot_hover
是NULL
的话,将NULL
传递给xintercept
)都会导致绘图出错. - 为什么当鼠标位于图的边界内时,
geom_vline
会在所有位置反弹吗?为什么当鼠标停止移动时它又回到x = 0?
- How can I get rid of the vertical line when the mouse is outside the bounds of the plot? Everything I've tried (like passing
NULL
toxintercept
ifinput$plot_hover
isNULL
) causes the plot to error out. - Why, when the mouse is inside the bounds of the plot, does the
geom_vline
bounce all over the place? Why does it go back to x = 0 when the mouse stops moving?
谢谢.
library(shiny)
library(ggplot2)
library(tidyr)
library(dplyr)
ui <- fluidPage(
titlePanel("Interactive Plot"),
sidebarLayout(
sidebarPanel(
sliderInput("points",
"Number of points:",
min = 10,
max = 50,
value = 25),
textOutput(outputId = "x.pos"),
textOutput(outputId = "y.pos"),
textOutput(outputId = "num_points")
),
mainPanel(
plotOutput("distPlot", hover = hoverOpts(id = "plot_hover",
delay = 100,
delayType = "throttle")))))
server <- function(input, output) {
# Create dataframe and plot object
plot <- reactive({
x <- 1:input$points
y1 <- seq(1,10 * input$points, 10)
y2 <- seq(20,20 * input$points, 20)
df <- data.frame(x,y1,y2)
df <- df %>% gather(key = series, value = value, y1:y2)
ggplot(df,aes(x=x, y=value, group=series, color=series)) +
geom_line() +
geom_point() +
geom_vline(xintercept = ifelse(is.null(input$plot_hover),0,input$plot_hover$x))
})
# Render Plot
output$distPlot <- renderPlot({plot()})
# Render mouse position into text
output$x.pos <- renderText(paste0("x = ",input$plot_hover$x))
output$y.pos <- renderText(paste0("y = ",input$plot_hover$y))
}
# Run the application
shinyApp(ui = ui, server = server)
推荐答案
解决此问题的建议解决方案是使用reactiveValues
和debounce
而不是throttle
.
A suggested solution to fix the issue is to use reactiveValues
and debounce
instead of throttle
.
问题
distPlot
取决于input$plot_hover$x
,它会连续更改或重置为null.
distPlot
depends on the input$plot_hover$x
which changes continuously, or gets reset to null.
建议的解决方案
-
使用
values <- reactiveValues(loc = 0)
来保存input$plot_hover$x
的值,并使用零或所需的任何值将其初始化.
use
values <- reactiveValues(loc = 0)
to hold the value ofinput$plot_hover$x
and initiate it with zero or any value you want.
使用observeEvent
,每当input$plot_hover$x
更改时更改loc
的值
use observeEvent
, to change the value of loc
whenever input$plot_hover$x
changes
observeEvent(input$plot_hover$x, {
values$loc <- input$plot_hover$x
})
observeEvent(input$plot_hover$x, {
values$loc <- input$plot_hover$x
})
使用debounce
而不是throttle
来在光标移动时暂停事件.
use debounce
instead of throttle
to suspend events while the cursor is moving.
我正在打印input$plot_hover$x
和values$loc
来告诉您区别.
I am printing input$plot_hover$x
and values$loc
to show you the difference.
注意:我对代码进行了一些更改,只是为了分解内容.
library(shiny)
library(ggplot2)
library(tidyr)
library(dplyr)
library(shinySignals)
ui <- fluidPage(
titlePanel("Interactive Plot"),
sidebarLayout(
sidebarPanel(
sliderInput("points",
"Number of points:",
min = 10,
max = 50,
value = 25),
textOutput(outputId = "x.pos"),
textOutput(outputId = "y.pos"),
textOutput(outputId = "num_points")
),
mainPanel(
plotOutput("distPlot", hover = hoverOpts(id = "plot_hover",
delay = 100,
delayType = "debounce")))))
server <- function(input, output) {
# Create dataframe and plot object
plot_data <- reactive({
x <- 1:input$points
y1 <- seq(1,10 * input$points, 10)
y2 <- seq(20,20 * input$points, 20)
df <- data.frame(x,y1,y2)
df <- df %>% gather(key = series, value = value, y1:y2)
return(df)
})
# use reactive values -------------------------------
values <- reactiveValues(loc = 0)
observeEvent(input$plot_hover$x, {
values$loc <- input$plot_hover$x
})
# if you want to reset the initial position of the vertical line when input$points changes
observeEvent(input$points, {
values$loc <- 0
})
# Render Plot --------------------------------------
output$distPlot <- renderPlot({
ggplot(plot_data(),aes(x=x, y=value, group=series, color=series))+
geom_line() +
geom_point()+
geom_vline(aes(xintercept = values$loc))
})
# Render mouse position into text
output$x.pos <- renderText(paste0("values$loc = ",values$loc))
output$y.pos <- renderText(paste0("input$plot_hover$x = ",input$plot_hover$x ))
}
# Run the application
shinyApp(ui = ui, server = server)
这篇关于闪亮:鼠标悬停点处带有垂直线和数据标签的交互式ggplot的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!