闪亮:鼠标悬停点处带有垂直线和数据标签的交互式ggplot [英] Shiny: Interactive ggplot with Vertical Line and Data Labels at Mouse Hover Point

查看:94
本文介绍了闪亮:鼠标悬停点处带有垂直线和数据标签的交互式ggplot的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想看看是否可以在有光泽的应用程序中创建折线图:

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:

通过鼠标悬停点的垂直线
鼠标悬停点x值处的点的数据标签

这是我第一次尝试使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:

  1. 当鼠标超出绘图范围时,如何摆脱垂直线?我尝试过的所有操作(例如,如果input$plot_hoverNULL的话,将NULL传递给xintercept)都会导致绘图出错.
  2. 为什么当鼠标位于图的边界内时,geom_vline会在所有位置反弹吗?为什么当鼠标停止移动时它又回到x = 0?
  1. 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 to xintercept if input$plot_hover is NULL) causes the plot to error out.
  2. 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)

推荐答案

解决此问题的建议解决方案是使用reactiveValuesdebounce而不是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 of input$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$xvalues$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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆