Interactive Plots with plotly
plotly is an R package that creates interactive web-based visualizations. It works seamlessly with ggplot2, allowing you to convert static charts into interactive ones with a single function call. This tutorial covers everything you need to know to create stunning interactive plots.
Installation and Setup
Install plotly from CRAN:
install.packages("plotly")
library(plotly)
Converting ggplot2 to plotly
The easiest way to get started with plotly is to convert your existing ggplot2 charts. Use ggplotly() to transform any ggplot into an interactive plotly object:
library(ggplot2)
library(plotly)
# Create a ggplot
p <- ggplot(mpg, aes(displ, hwy, color = class)) +
geom_point() +
labs(title = "Fuel Efficiency by Engine Displacement",
x = "Engine Displacement (L)",
y = "Highway MPG")
# Convert to interactive plotly
ggplotly(p)
The resulting plot now has hover tooltips showing exact values, zoom capabilities, and the ability to save as PNG.
Creating plotly Charts from Scratch
For full control, create plotly charts directly using plot_ly(). The syntax uses the pipe operator %>% to add layers:
plot_ly(mpg, x = ~displ, y = ~hwy, color = ~class, type = "scatter", mode = "markers") %>%
layout(title = "Fuel Efficiency by Class",
xaxis = list(title = "Engine Displacement (L)"),
yaxis = list(title = "Highway MPG"))
Interactive Bar Charts
Create interactive bar charts that reveal values on hover:
plot_ly(diamonds, x = ~cut, y = ~price, color = ~clarity, type = "bar") %>%
layout(barmode = "stack",
title = "Diamond Prices by Cut and Clarity",
xaxis = list(title = "Cut"),
yaxis = list(title = "Price ($)"))
Line Charts and Time Series
For time series data, plotly handles dates automatically:
# Sample time series data
data <- data.frame(
date = seq(as.Date("2025-01-01"), by = "month", length.out = 12),
value = cumsum(rnorm(12, mean = 10, sd = 5))
)
plot_ly(data, x = ~date, y = ~value, type = "scatter", mode = "lines+markers") %>%
layout(title = "Monthly Revenue Trend",
xaxis = list(title = "Month"),
yaxis = list(title = "Revenue ($)"))
Box Plots
Box plots in plotly are fully interactive, showing quartiles on hover:
plot_ly(diamonds, x = ~cut, y = ~price, color = ~cut, type = "box") %>%
layout(title = "Price Distribution by Cut Quality",
xaxis = list(title = "Cut"),
yaxis = list(title = "Price ($)"))
Heatmaps
Visualize matrix data with interactive heatmaps:
# Create correlation matrix
corr <- cor(mtcars)
plot_ly(z = corr, x = names(mtcars), y = names(mtcars), type = "heatmap") %>%
layout(title = "Car Features Correlation Matrix")
Customizing Tooltips
Control exactly what appears in hover tooltips using the text aesthetic:
plot_ly(mpg, x = ~displ, y = ~hwy,
text = ~paste("Model:", model, "<br>Year:", year),
hoverinfo = "text+x+y",
type = "scatter", mode = "markers") %>%
layout(title = "Custom Hover Information")
Interactive 3D Plots
plotly excels at 3D visualizations that you can rotate and explore:
plot_ly(mtcars, x = ~wt, y = ~hp, z = ~qsec, color = ~disp,
type = "scatter3d", mode = "markers") %>%
layout(title = "Car Performance in 3D")
Building Interactive Dashboards
Combine multiple plots into a dashboard using subplot:
# Create individual plots
p1 <- plot_ly(mpg, x = ~displ, y = ~hwy, type = "scatter", mode = "markers")
p2 <- plot_ly(mpg, x = ~class, y = ~hwy, type = "box")
p3 <- plot_ly(mpg, x = ~cyl, type = "histogram")
# Combine into dashboard
subplot(p1, p2, p3, nrows = 2)
Saving and Sharing
Export your interactive plots as HTML files that can be shared and viewed in any browser:
# Save as standalone HTML
saveWidget(plot_ly(mpg, x = ~displ, y = ~hwy, type = "scatter", mode = "markers"),
file = "interactive-plot.html")
# Or embed in R Markdown / Quarto documents
Summary
plotly transforms your R visualizations into interactive experiences. Key functions to remember:
ggplotly()— Convert ggplot2 charts instantlyplot_ly()— Create plots from scratchsubplot()— Combine multiple plotssaveWidget()— Export as standalone HTML
With these tools, you can create compelling interactive visualizations that engage your audience and reveal data insights dynamically.