How do I show the y value on tooltip while hover in ggplot2

前端 未结 1 1290
别跟我提以往
别跟我提以往 2020-12-01 00:19

I want the show the y-value when I hold my mouse on a point in the graph. The code for my plot looks like this:

output$graph <- renderPlot({
  p1 <- gg         


        
相关标签:
1条回答
  • 2020-12-01 01:04

    Unfortunately ggplot is not interactive but it can be easily "fixed" with plotly package. You only need to replace plotOutput with plotlyOutput and then render a plot on with renderPlotly.

    Example 1: plotly

    library(shiny)
    library(ggplot2)
    library(plotly)
    
    ui <- fluidPage(
        plotlyOutput("distPlot")
    )
    
    server <- function(input, output) {
       output$distPlot <- renderPlotly({
          ggplot(iris, aes(Sepal.Width, Petal.Width)) + 
           geom_line() + 
           geom_point()
       })
    }
    
    shinyApp(ui = ui, server = server)
    



    Example 2: plotOutput(..., hover = "plot_hover"):

    We don't have to use any special package to introduce the interactivity to our graphs though. All we need is our lovely shiny shiny! We can just play with plotOutput options as for instance click, hover or dblclick to make the plot interactive. (See more examples in shiny gallery)

    In the example below we add "hovering" by hover = "plot_hover" and then specify delay which is by default 300ms.

    plotOutput("distPlot", hover = "plot_hover", hoverDelay = 0)
    

    We then can access values via input$plot_hover and use a function nearPoints to show values that are near the points.

    ui <- fluidPage(
      selectInput("var_y", "Y-Axis", choices = names(iris)),
      plotOutput("distPlot", hover = "plot_hover", hoverDelay = 0),
      uiOutput("dynamic")
    
    )
    
    server <- function(input, output) {
    
      output$distPlot <- renderPlot({
        req(input$var_y)
        ggplot(iris, aes_string("Sepal.Width", input$var_y)) + 
          geom_point()
      })
    
      output$dynamic <- renderUI({
        req(input$plot_hover) 
        verbatimTextOutput("vals")
      })
    
      output$vals <- renderPrint({
        hover <- input$plot_hover 
        # print(str(hover)) # list
        y <- nearPoints(iris, input$plot_hover)[input$var_y]
        req(nrow(y) != 0)
        y
      })
    
    }
    shinyApp(ui = ui, server = server)
    

    Example 3: Custom ggplot2 tooltip:

    The second solution works great but yes...we want to do it better! And yes...we can do it better! (...If we use some javaScript but pssssss don't tell anyone!).

    library(shiny)
    library(ggplot2)
    
    ui <- fluidPage(
    
      tags$head(tags$style('
         #my_tooltip {
          position: absolute;
          width: 300px;
          z-index: 100;
          padding: 0;
         }
      ')),
    
      tags$script('
        $(document).ready(function() {
          // id of the plot
          $("#distPlot").mousemove(function(e) { 
    
            // ID of uiOutput
            $("#my_tooltip").show();         
            $("#my_tooltip").css({             
              top: (e.pageY + 5) + "px",             
              left: (e.pageX + 5) + "px"         
            });     
          });     
        });
      '),
    
      selectInput("var_y", "Y-Axis", choices = names(iris)),
      plotOutput("distPlot", hover = "plot_hover", hoverDelay = 0),
      uiOutput("my_tooltip")
    
    
    )
    
    server <- function(input, output) {
    
    
      output$distPlot <- renderPlot({
        req(input$var_y)
        ggplot(iris, aes_string("Sepal.Width", input$var_y)) + 
          geom_point()
      })
    
      output$my_tooltip <- renderUI({
        hover <- input$plot_hover 
        y <- nearPoints(iris, input$plot_hover)[input$var_y]
        req(nrow(y) != 0)
        verbatimTextOutput("vals")
      })
    
      output$vals <- renderPrint({
        hover <- input$plot_hover 
        y <- nearPoints(iris, input$plot_hover)[input$var_y]
        req(nrow(y) != 0)
        y
      })  
    }
    shinyApp(ui = ui, server = server)
    



    Example 4: ggvis and add_tooltip:

    We can also use ggvis package. This package is great, however, not enough mature yet.

    Update: ggvis is currently dormant: https://github.com/rstudio/ggvis#status

    library(ggvis)
    
    ui <- fluidPage(
      ggvisOutput("plot")
    )
    
    server <- function(input, output) {
    
      iris %>%
        ggvis(~Sepal.Width, ~Petal.Width) %>%
        layer_points() %>%
        layer_lines() %>% 
        add_tooltip(function(df) { paste0("Petal.Width: ", df$Petal.Width) }) %>%
        bind_shiny("plot")
    }
    
    shinyApp(ui = ui, server = server)
    

    EDITED


    Example 5:

    After this post I searched internet to see whether it could be done more nicely than example 3. I found this wonderful custom tooltip for ggplot and I believe it can hardly be done better than that.

    0 讨论(0)
提交回复
热议问题