Interactive Visualizations with plotly
Interactive visualizations let your audience explore data rather than just view static images. The plotly package provides R programmers with a powerful way to build interactive charts that work in HTML documents, Shiny apps, and standalone HTML files.
Unlike static ggplot2 images, plotly charts respond to user input. Viewers can hover to see exact values, click legend items to filter categories, zoom into regions of interest, and pan around large datasets. This makes plotly ideal for exploratory data analysis and presenting findings to stakeholders who need to dig into the numbers themselves.
Installing plotly
Install plotly from CRAN or get the development version from GitHub:
# From CRAN
install.packages("plotly")
# Or from GitHub for latest features
# remotes::install_github("plotly/plotly.R")
Load it alongside tidyverse if you prefer:
library(plotly)
library(tidyverse)
Converting ggplot2 to plotly
If you already know ggplot2, plotly makes it easy to convert your existing plots to interactive versions without rewriting everything. The ggplotly() function takes a ggplot object and returns an interactive plotly object:
# Create a ggplot first
p <- ggplot(mpg, aes(displ, hwy, color = class)) +
geom_point() +
labs(title = "Fuel Efficiency by Engine Displacement",
x = "Engine Displacement (L)",
y = "Highway MPG") +
theme_minimal()
# Convert to interactive plotly
ggplotly(p)
This approach lets you build visualizations with familiar ggplot2 syntax, then add interactivity afterward. Hover over points to see values, click legend items to toggle categories, and drag to zoom. The conversion preserves most aesthetics including colors, shapes, and transparency.
Basic Interactive Charts
Plotly also works directly with its own syntax. Here is how to create common chart types:
Scatter Plot
plot_ly(data = mtcars, x = ~wt, y = ~mpg,
color = ~factor(cyl),
type = "scatter", mode = "markers") %>%
layout(title = "Car Weight vs MPG",
xaxis = list(title = "Weight (1000 lbs)"),
yaxis = list(title = "Miles per Gallon"))
Bar Chart
plot_ly(data = count(mpg, class), x = ~class, y = ~n,
type = "bar",
marker = list(color = "steelblue")) %>%
layout(title = "Cars per Class",
yaxis = list(title = "Count"))
Histogram
plot_ly(data = iris, x = ~Sepal.Length, type = "histogram") %>%
layout(title = "Sepal Length Distribution")
3D Visualizations
Plotly supports 3D scatter plots and surfaces, which are useful for exploring multivariate data that would be hard to see in two dimensions:
plot_ly(data = iris, x = ~Sepal.Length, y = ~Sepal.Width,
z = ~Petal.Length, color = ~Species) %>%
add_markers() %>%
layout(scene = list(xaxis = title("Sepal Length"),
yaxis = title("Sepal Width"),
zaxis = title("Petal Length")))
3D plots can be rotated by clicking and dragging, letting you find angles that reveal patterns in your data. Use them sparingly though - they can be harder to interpret than 2D views.
Creating Subplots
Combine multiple plots into one figure using subplot() when you need to compare different views side by side:
p1 <- plot_ly(data = mtcars, x = ~wt, y = ~mpg, type = "scatter", mode = "markers")
p2 <- plot_ly(data = mtcars, x = ~wt, y = ~disp, type = "scatter", mode = "markers")
p3 <- plot_ly(data = mtcars, x = ~wt, y = ~hp, type = "scatter", mode = "markers")
subplot(p1, p2, p3, nrows = 1, shareX = TRUE, titleX = FALSE)
Set shareX = TRUE to synchronize zooming across all subplots, which is helpful when comparing variables against the same scale.
Animations
Create animated visualizations that cycle through categories to show how values change over time or across groups:
plot_ly(data = mtcars, x = ~wt, y = ~mpg,
frame = ~factor(cyl),
type = "scatter", mode = "markers") %>%
animation_opts(frame = 1000, transition = 800)
The frame argument specifies which variable to animate through. Use this to build narratives around change over time or categorical transitions.
Customizing Layout
The layout() function controls titles, axes, legends, and styling:
plot_ly(data = mtcars, x = ~wt, y = ~mpg, type = "scatter", mode = "markers") %>%
layout(
title = list(text = "Weight vs MPG", font = list(size = 20)),
xaxis = list(title = "Weight", showgrid = FALSE),
yaxis = list(title = "MPG", showgrid = TRUE),
plot_bgcolor = "#f0f0f0",
paper_bgcolor = "white"
)
Sharing Your Visualizations
Interactive plotly charts render as HTML widgets. Save them as standalone HTML files:
# Save to HTML file
htmlwidgets::saveWidget(plot_ly(data = mtcars, x = ~wt, y = ~mpg,
type = "scatter", mode = "markers"),
"my-plot.html")
Or embed them in R Markdown documents or Shiny apps for web-based presentations.
See Also
base-r-plotting— Static visualization with ggplot2r-interactive-leaflet— Interactive maps with leafletr-ggplot2-extensions— ggplot2 Extensions