Jam
Jam

Reputation: 75

R interactive plot: show vertical line on hover

I have been looking around for a way to draw a vertical line along the x-axis when hovering over points in a plot using R. It does not really matter which package it is, whether it is plotly, ggvis, rCharts, googleVis or any other for that matter, but I would rather use one of the these mentioned ones if possible.

Here is an example of what I would like to have.

Upvotes: 4

Views: 4596

Answers (3)

Vance Lopez
Vance Lopez

Reputation: 1358

A partial answer (can't comment)... Plotly has type "scattergl" which draws a horizontal and vertical line on hover.

Data

require(plotly)    

sdate <- as.Date("2015-01-01", format = "%Y-%m-%d")
timedf <- data.frame(Date = seq.Date(sdate, by="month", length.out=12),
                         Amount = runif(12, 0, 100))
# Plotly plot
plot_ly(timedf, x=Date, y=Amount, type="scattergl")

Output enter image description here

Upvotes: 3

GL_Li
GL_Li

Reputation: 1798

Follow Chris' answer, to make it work

library(ggplot2)
library(shiny)

ui <- fluidPage(
    fluidRow(
        column(width = 12,
               plotOutput("plot1", height = 350,hover = "plot_hover")
        )
    )
)

server <- function(input, output) {
    testPlot <- ggplot(mtcars, aes(x=mpg,y=disp,color=factor(cyl))) + 
        geom_point()

    #start up plot
    output$plot1 <- renderPlot({testPlot})

    # plot after mouse over
    observeEvent(input$plot_hover, {
        x = input$plot_hover$x
        y = input$plot_hover$y
        nearPoint <- nearPoints(mtcars, input$plot_hover, 
                                threshold = 10, maxpoints = 1)
        output$plot1 <- renderPlot({
            if (nrow(nearPoint) == 1) {
                testPlot + 
                    geom_vline(xintercept = nearPoint$mpg) +
                    geom_label(x = x + 1.5, y = y, 
                               label = paste(rownames(nearPoint), "\n", nearPoint$disp))
            } else {
                testPlot
            }
        })
    })
}

shinyApp(ui, server)

enter image description here

Upvotes: 3

Chris C
Chris C

Reputation: 1655

Here's a partial answer. I can't quite get it to work, but maybe someone will see something obvious. I've used ggplot2 instead of ggvis for the geom_vline() function which creates a vertical line.

What's working:

On the input$plot_hover event, we assign the x coordinate to a variable (h) and then use that variable as the xintercept arguement to the geom_vline() function which draws a vertical line.

The problem:

Since this is happening in a reactive environment, on every update h is flushed, so the line disappears about a second after it first appears.

What I've tried:

I tried to assign h to a second variable t in order to keep it between updates. This didn't work, so I created a third variable prev_t and when there was no input (is.null(input$plot_hover) == TRUE), keep t as prev_t. This also isn't working but I don't have a ton of time to try out different things.

Here's the code:

library(ggplot2)
library(shiny)

ui <- fluidPage(
    fluidRow(
        column(width = 12,
               plotOutput("plot1", height = 350,hover = hoverOpts(id ="plot_hover"))
        )
    )
)

server <- function(input, output) {
    
   #h <- reactive(input$plot_hover)

   prev_t <- vector()

    output$plot1 <- renderPlot({

        if(!is.null(input$plot_hover)){
            x <- input$plot_hover
            h <- x$x
            t <- h


        # the below isnt quite working
        # I was trying to store t between updates to make the line stay on 
        # the graph until there was a second hover event

        ################### !!! ###################
        } else if(is.null(input$plot_hover)) {
            t <- prev_t
        }

        prev_t <- t
        ################## !!! ####################

        ggplot(mtcars, aes(x=mpg,y=disp,color=factor(cyl))) + geom_point() + geom_vline(xintercept = t)

    })


}
shinyApp(ui, server)

Hopefully that should maybe put you on a different path or help a little. If someone sees something that could fix this problem, please let me know.

Upvotes: 1

Related Questions