20  Interactive Graphics

20.1 Introduction

In this chapter, we introduce tools for creating interactive visualizations, which can help reveal insights that static plots might miss. Interactive plots are particularly useful in entrepreneurial scenarios where exploration and presentation of dynamic data are critical for decision-making. For example, imagine being able to interactively change visualization parameters while in the middle of an investor pitch. To do this, we’ll focus on two powerful tools: Plotly and Shiny

To demonstrate how these tools can create interactivity, we wil use the Liberty ship data first seen in Section 18.2. As before, we will primarily explore the evolution of the relationship between Direct_Hours and Total_Production_Days as we seek to understand the dynamic improvements in productivity.

# A tibble: 1,571 × 6
    Unit Yard        Way Direct_Hours Total_Production_Days Total_Cost
   <dbl> <chr>     <dbl>        <dbl>                 <dbl>      <dbl>
 1     1 Bethlehem     1       870870                   244   2615849 
 2     2 Bethlehem     2       831745                   249   2545125 
 3     3 Bethlehem     3       788406                   222   2466811 
 4     4 Bethlehem     4       758934                   233   2414978 
 5     5 Bethlehem     5       735197                   220   2390643 
 6     6 Bethlehem     6       710342                   227   2345051 
 7     8 Bethlehem     8       668785                   217   2254490 
 8     9 Bethlehem     9       675662                   196   2139564.
 9    10 Bethlehem    10       652911                   211   2221499.
10    11 Bethlehem    11       603625                   229   2217642.
# ℹ 1,561 more rows

20.2 Converting ggplot2 to Interactive with Plotly

Plotly makes it easy to add interactivity to plots created with ggplot2. You can transform static plots into interactive ones by wrapping them with ggplotly().

We’ll start with a scatter plot of Direct_Hours and Total_Production_Days, showing a static visualization of the relationship between labor hours and production time.

library(ggplot2)
# Static ggplot2 visualization
liberty_plot <- liberty_ship_data |> 
  ggplot(aes(x = Direct_Hours, y = Total_Production_Days, color = Yard)) + 
  geom_point() + 
  labs( title = "Liberty Ship Production Time vs. Labor Hours", 
        x = "Direct Labor Hours", y = "Total Production Days" ) + 
  theme_minimal()
liberty_plot

Now let’s convert the scatter plot to an interactive plot with ggplotly.

library(plotly)
interactive_plot <- ggplotly(liberty_plot) 
interactive_plot

Explanation

  • ggplotly() transformed the ggplot object into an interactive plot
  • Hovering over points shows details about the data (e.g., Yard, Direct_Hours, Total_Production_Days).
  • You can zoom, pan, and save the plot as an image directly from the interactive interface.

Exercise: Add Labels

Try it yourself


Customer responses about the protein-infused Muscle Cola were introduced in Chapter 18 in the exercise generating a scatter plot in Section 18.5.2. Using muscle_cola_data

  1. Plot the relationship between willingness to pay WTP and monthly consumption Quantity.

  2. Map the variable Gym_member to color to show how gym membership affects the relationship between willingness to pay WTP and consumption Quantity.

  3. Map the length of the respondent’s workout Workout_length to shape to show how workout length affects the relationship.

  4. Add title and axes labels

    • Make the title “Willingness to Pay and Consume Muscle Cola”
    • Make the x-axis “Willingness to Pay”
    • Make the y-axis “Quantity Consumed”

Hint 1

Re-build your plot from layers beginning with specifying the dataset, then specifying aesthetic mapping of the x- and y-variables as well as the aesthetic mapping of gym membership to color. Inside a new aesthetic mapping in the point geometry, map the shape of the point to the length of the workout. Then declare the geometry to plot the data points. Then add the title and labels as instructed.

Hint 2

Inside the ggplot function, add the argument that the dataset is muscle_cola_data and the aesthetic mapping aes() the specifies that willingness to pay WTP is the x variable and Quantity is the y variable. Add an argument inside the aesthetic mapping that maps color to Gym_member. Then call the geom_point() function to plot the data as points (scatter plot). Add an aesthetic mapping of shape to Workout_length inside the geom_point(). Then call the labs() function using arguments title = "Willingness to Pay and Consume Muscle Cola", x = "Willingness to Pay", y = "Quantity Consumed".

  labs(title = "Willingness to Pay and Consume Muscle Cola", 
       x = "Willingness to Pay", 
       y = "Quantity Consumed"
       )

Fully worked solution:

As arguments to the ggplot() function, declare the data as muscle_cola_data and the aesthetic mapping as aes(x = WTP, y = Quantity, color = Gym_member). Then call the geom_point() function to plot the data as points. Then call the labs() function to add the title and axes labels.

1ggplot(muscle_cola_data,
2       aes(x = WTP, y = Quantity, color = Gym_member)) +
3  geom_point(aes(shape = Workout_length)) +
4  labs(title = "Willingness to Pay and Consume Muscle Cola",
5       x = "Willingness to Pay",
6       y = "Quantity Consumed")
1
Call the ggplot() function and specify muscle_cola_data as the data
2
Specify that aesthetic mapping with WTP plotted on the x-axis and Quantity on the y-axis, adding the mapping of color to Gym_member
3
Call the geom_point() function to get a scatter plot of points and add the aesthetic that maps shape to the Workout_length
4
Call the labs() function and specify the title
5
Specify the x-axis label
6
Specify the y-axis label

20.3 Building Standalone Interactive Plots in Plotly

Plotly also allows you to create interactive plots directly using its API. These standalone visualizations don’t require ggplot2.

Example: Liberty Ship Data in 3D

Let’s visualize labor hours, production time, and cost in a 3D scatter plot. We will do this using only the plot_ly() function of Plotly.

# Example: 3D scatter plot with Plotly
plot_ly( data = liberty_ship_data, 
         x = ~Direct_Hours, 
         y = ~Total_Production_Days, 
         z = ~Total_Cost, 
         color = ~Yard, 
         type = "scatter3d", 
         mode = "markers", 
         marker = list(size = 5) ) |>
  layout( title = "3D Visualization of Liberty Ship Production", 
          scene = list( xaxis = list(title = "Direct Labor Hours"), 
                        yaxis = list(title = "Total Production Days"), 
                        zaxis = list(title = "Total Cost") ) ) 

Interactive Features to Explore

The interactive plot_ly visualization offers powerful tools for exploring the Liberty Ship data dynamically. Try out the following features:

  • Dynamic Labels: Hover over any data point to view detailed information, including exact values and shipyard identifiers, for a richer understanding of the data.
  • Dynamic Filtering: Click on a shipyard in the legend to toggle its visibility in the plot. This allows you to focus on specific categories dynamically, enabling customized comparisons and clearer insights.
  • 3D Exploration: Rotate, zoom, and pan to examine the data from different perspectives, revealing patterns and relationships that may not be immediately apparent in a static plot.

20.4 Basics of Shiny for Dynamic Dashboards

Shiny is a powerful R package for building interactive web applications. It enables users to create dashboards that dynamically respond to inputs, such as filters or sliders.

Example: Shiny Dashboard for Liberty Ship Data

Create a dashboard where users can filter data by shipyard and view the corresponding scatter plot.

library(shiny)

#Define UI
ui <- fluidPage( titlePanel("Liberty Ship Production Dashboard"), sidebarLayout( sidebarPanel( selectInput("yard", "Select Shipyard:", choices = unique(liberty_ship_data$Yard), selected = unique(liberty_ship_data$Yard)[1]) ), mainPanel( plotlyOutput("scatterPlot") ) ) )

#Define Server
server <- function(input, output) { output$scatterPlot <- renderPlotly({ filtered_data <- liberty_ship_data %>% filter(Yard == input$yard)

plot_ly(
  data = filtered_data,
  x = ~Direct_Hours,
  y = ~Total_Production_Days,
  type = "scatter",
  mode = "markers",
  marker = list(size = 8, color = "blue")
) %>%
  layout(
    title = paste("Production Data for Shipyard:", input$yard),
    xaxis = list(title = "Direct Labor Hours"),
    yaxis = list(title = "Total Production Days")
  )
}) }

#Run the app
shinyApp(ui = ui, server = server) 

Instructions:

  1. Save this script and run it in RStudio or an R environment.
  2. Launch the app to explore Liberty Ship data interactively.
  3. Select a shipyard from the dropdown to filter data dynamically.

Interactive visualizations enhance decision-making by enabling deeper exploration and dynamic presentation of insights.