# 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 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.
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_ship_data |>
liberty_plot 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)
<- ggplotly(liberty_plot)
interactive_plot interactive_plot
Explanation
ggplotly()
transformed theggplot
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
Plot the relationship between willingness to pay
WTP
and monthly consumptionQuantity.
Map the variable
Gym_member
to color to show how gym membership affects the relationship between willingness to payWTP
and consumptionQuantity.
Map the length of the respondent’s workout
Workout_length
to shape to show how workout length affects the relationship.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,
2aes(x = WTP, y = Quantity, color = Gym_member)) +
3geom_point(aes(shape = Workout_length)) +
4labs(title = "Willingness to Pay and Consume Muscle Cola",
5x = "Willingness to Pay",
6y = "Quantity Consumed")
- 1
-
Call the
ggplot()
function and specifymuscle_cola_data
as the data - 2
-
Specify that aesthetic mapping with
WTP
plotted on the x-axis andQuantity
on the y-axis, adding the mapping of color toGym_member
- 3
-
Call the
geom_point()
function to get a scatter plot of points and add the aesthetic that mapsshape
to theWorkout_length
- 4
-
Call the
labs()
function and specify thetitle
- 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
<- 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") ) ) )
ui
#Define Server
<- function(input, output) { output$scatterPlot <- renderPlotly({ filtered_data <- liberty_ship_data %>% filter(Yard == input$yard)
server
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:
- Save this script and run it in RStudio or an R environment.
- Launch the app to explore Liberty Ship data interactively.
- Select a shipyard from the dropdown to filter data dynamically.
Interactive visualizations enhance decision-making by enabling deeper exploration and dynamic presentation of insights.
20.5 Gallery of Shiny Apps
- Shiny gallery at Posit
- Shinylive examples (for R)
- Shinylive examples (for Python)
- Quarto gallery of Dashboards
- Quarto gallery of Interactive Docs