Interactive plots

As of version 0.12.0, Shiny has built-in support for interacting with static plots generated by R’s base graphics functions, and those generated by ggplot2.
Published

October 15, 2019

As of version 0.12.0, Shiny has built-in support for interacting with static plots generated by R’s base graphics functions, and those generated by ggplot2.

This makes it easy to add features like selecting points and regions, as well as zooming in and out of images.

Basics

To get the position of the mouse when a plot is clicked, you simply need to use the click option with the plotOutput(). For example, this will define a new input value, input$plot_click, which contains the location of the previous mouse click.

plotOutput("plot1", click = "plot_click")

For example, this app will print out the x and y coordinate position of the mouse cursor when a click occurs (to see it in action, click in the plot area of the app rendered below the code):

library(shiny)

ui <- basicPage(
  plotOutput("plot1", click = "plot_click"),
  verbatimTextOutput("info")
)

server <- function(input, output) {
  output$plot1 <- renderPlot({
    plot(mtcars$wt, mtcars$mpg)
  })

  output$info <- renderText({
    paste0("x=", input$plot_click$x, "\ny=", input$plot_click$y)
  })
}

shinyApp(ui, server)

Notice that the x and y coordinates are scaled to the data, as opposed to simply being the pixel coordinates. This makes it easy to use those values to select or filter data.

The other types of interactions are double-clicking, hovering, and brushing. (Brushing is clicking and dragging a selection box.) They can be enabled with the dblclick, hover, and brush options. In the example below, all of these are enabled, and the coordinates are displayed below

ui <- basicPage(
  plotOutput("plot1",
    click = "plot_click",
    dblclick = "plot_dblclick",
    hover = "plot_hover",
    brush = "plot_brush"
  ),
  verbatimTextOutput("info")
)

server <- function(input, output) {
  output$plot1 <- renderPlot({
    plot(mtcars$wt, mtcars$mpg)
  })

  output$info <- renderText({
    xy_str <- function(e) {
      if(is.null(e)) return("NULL\n")
      paste0("x=", round(e$x, 1), " y=", round(e$y, 1), "\n")
    }
    xy_range_str <- function(e) {
      if(is.null(e)) return("NULL\n")
      paste0("xmin=", round(e$xmin, 1), " xmax=", round(e$xmax, 1), 
             " ymin=", round(e$ymin, 1), " ymax=", round(e$ymax, 1))
    }

    paste0(
      "click: ", xy_str(input$plot_click),
      "dblclick: ", xy_str(input$plot_dblclick),
      "hover: ", xy_str(input$plot_hover),
      "brush: ", xy_range_str(input$plot_brush)
    )
  })
}

shinyApp(ui, server)

While click, dblclick, and hover have x and y coordinates, brush is slightly different: because it’s a box, it has xmin, xmax, ymin, and ymax.

Next: learn about how to easily select rows of data with interactive plots.

Learn more

For more on this topic, see the following resources:

Coordinated multiple views (linked brushing)