Visualizations capable of launching detail views can add value to a data analyst’s user experience. Programming in this kind of interaction automates the creation of complementary charts and increases ease of exploration by linking varied views of the data in a logical way.
This tutorial offers a quick example of how to create a click input function with Shiny.onInputChange in JavaScript. The visualization used for this example is a heatmap drawn with Highcharts, since the hc_add_event_point function in the R library highcharter does not apply for clicks on heatmaps as of this writing. A similar approach can likewise be applied to any visualization drawn with highcharter , whenever the data retrieved and sent from a JavaScript object to R requires customization.
library(shiny) library(highcharter) library(ggplot2) red_wine <- read.csv('winequality-red.csv', sep = ';')
Exploring relationships among variables in a dataset is an important first step in getting to know and prepping data for machine learning.
Whenever a cell is clicked on the correlation matrix below, the graph will yield a scatter plot of the two variables corresponding to that specific correlation value.
The Wine Quality dataset from the University of California, Irvine data archive for machine learning datasets was used. The data can be downloaded here.
The chart above requires the following R libraries:
library(shiny) library(highcharter) library(ggplot2)
We read in the data as red_wine :
red_wine <- read.csv('winequality-red.csv', sep = ';')
From there, generating the heatmap with highcharter is simple. In the code for our simple Shiny app below, we apply the cor function to the data, then pass the resulting matrix to hchart .
We add the JavaScript function that extracts the x and y data series names from the correlation matrix inside hc_plotOptions as a click event. The event parameter is a matrix cell click, a JavaScript object we can deconstruct. Using this object that we have named event , we create the xstr and ystr variables.
From there, we can build the data structure to be returned: an array called data with the variables x , y , and nonce . The nonce variable, simply a random number, is commonly used in click interactions: its purpose is to allow for two consecutive clicks on the same element. Otherwise, the event data will be the same as before, and JavaScript will not interpret this event as a change, remaining unresponsive until the user clicks on a different element.
We call the JavaScript function Shiny.onInputChange to send a custom message from JavaScript to Shiny. The first parameter matrix_click is the unique name for the event which Shiny observers and reactive functions can listen for. We can now refer to the event as input$matrix_click elsewhere in our code, as we would for other Shiny inputs. The second parameter, data , is the custom message to be sent from JavaScript to R after every click event.
shinyApp( ui <- fluidPage( # Application title titlePanel("Red Wine Quality") , fluidRow(column(8 , highchartOutput('wine_corr', height = "600px") ) ) ), server <- function(input, output, session) { # remove `quality` rating red_wine <- subset(red_wine, select = -quality) red_wine_corr <- cor(red_wine) output$wine_corr <- renderHighchart({ hchart(red_wine_corr) %>% hc_plotOptions( series = list( boderWidth = 1, dataLabels = list(enabled = FALSE), events = list( click = JS("function(event) { var xstr = event.point.series.xAxis.categories[event.point.x].toString(); var ystr = event.point.series.yAxis.categories[event.point.y].toString(); var data = { x: xstr, y: ystr, nonce: Math.random() }; Shiny.onInputChange('matrix_click', data); }")) ) ) }) # event listener observeEvent(input$matrix_click, { # retrieve series from red_wine using x and y variables from click data red_wine$x_val <- red_wine[[input$matrix_click$x]] red_wine$y_val <- red_wine[[input$matrix_click$y]] # code for ggplot scatter plot output$scatterPlot <- renderPlot({ ggplot(red_wine, aes(x=x_val, y=y_val)) + geom_point() + ylab(input$matrix_click$y) + xlab(input$matrix_click$x) }) # overlay with ggplot scatter plot showModal( modalDialog( fluidRow( column(12, h3(paste0(input$matrix_click$y, " ~ ", input$matrix_click$x)) ) ) , plotOutput("scatterPlot") , size = "l" , easyClose = TRUE ) ) }) }, options = list( width = "100%", height = 750 ) )
We can now capture the variable names for any given value in the correlation matrix as a click input. Using these variable names to access the original data series, Shiny can spin up scatter plots on the fly. Not only can we compare correlation values by looking at the cell colors of the correlation matrix, we can also zero in on the shape of variable relationships of interest. A different, more detailed view of the data is just a click away.