Data visualization is a bridge between raw data and actionable insights. While R offers numerous tools for creating beautiful plots, the leap from static graphics to interactive visualizations can dramatically improve understanding, storytelling, and engagement. Among R’s visualization libraries, Plotly stands out for its ability to transform ordinary plots into rich, interactive, and shareable experiences without requiring extensive knowledge of JavaScript, HTML, or CSS.
In this guide, we’ll explore Plotly in R — from its fundamentals to advanced interactive visualizations — providing practical examples you can implement immediately.
While popular libraries like ggplot2 excel at creating static charts, they have limitations when it comes to interactivity. ggvis addresses some of this but can be less performant and harder to customize for complex dashboards. This is where Plotly shines.
Key advantages of Plotly:
ggplot2, allowing you to convert static plots into interactive charts.Limitations to be aware of:
Begin by installing and loading the Plotly package:
install.packages("plotly")library(plotly)
Plotly works well alongside dplyr and ggplot2, so we often load them too:
library(dplyr)library(ggplot2)
The basic function for creating a Plotly plot is:
plot_ly(x, y, type, mode, color, size)
Where:
x, y → axis valuestype → type of chart (scatter, bar, histogram, etc.)mode → representation mode (lines, markers, or lines+markers)color → color mapping for categorical variablessize → scales marker sizes according to a numeric variableLet’s start with a scatterplot using the built-in iris dataset:
data(iris)head(iris)
The dataset contains four continuous variables (Sepal.Length, Sepal.Width, Petal.Length, Petal.Width) and one categorical variable (Species). To create a basic scatterplot:
scatter <- plot_ly(iris, x = ~Sepal.Length, y = ~Petal.Length, type = 'scatter', mode = 'markers')layout(scatter, title = "Sepal vs Petal Length", xaxis = list(title = "Sepal Length"), yaxis = list(title = "Petal Length"))
We can differentiate species using color and scale marker size by Sepal.Length:
scatter <- plot_ly(iris, x = ~Sepal.Length, y = ~Petal.Length, type = 'scatter', mode = 'markers', color = ~Species, size = ~Sepal.Length)layout(scatter, title = "Interactive Scatterplot by Species", xaxis = list(title = "Sepal Length"), yaxis = list(title = "Petal Length"))
Interactivity features include:
Plotly excels at time series and line charts. Consider the airquality dataset:
data(airquality)plot_ly(airquality, x = ~Day, y = ~Solar.R, type = 'scatter', mode = 'lines+markers') %>% layout(title = "Daily Solar Radiation", xaxis = list(title = "Day"), yaxis = list(title = "Solar.R"))
This chart provides interactive exploration of trends, enabling analysts to zoom into specific days or inspect individual points easily.
plot_ly(iris, x = ~Sepal.Length, type = 'histogram') %>% layout(title = "Distribution of Sepal Length", xaxis = list(title = "Sepal Length"), yaxis = list(title = "Count"))
plot_ly(iris, x = ~Species, y = ~Sepal.Length, type = 'bar') %>% layout(title = "Average Sepal Length by Species", xaxis = list(title = "Species"), yaxis = list(title = "Sepal Length"))
For grouped data:
Animals <- c("Giraffes", "Orangutans", "Monkeys")SF_Zoo <- c(20, 14, 23)LA_Zoo <- c(12, 18, 29)zoo_data <- data.frame(Animals, SF_Zoo, LA_Zoo)plot_ly(zoo_data, x = ~Animals, y = ~SF_Zoo, type = 'bar', name = 'SF Zoo') %>% add_trace(y = ~LA_Zoo, name = 'LA Zoo') %>% layout(title = "Zoo Animal Counts", yaxis = list(title = "Count"), barmode = 'stack')
Plotly allows layering multiple traces in a single chart. For example:
set.seed(123)data <- data.frame(x = 1:100, trace1 = rnorm(100, 0, 1), trace2 = rnorm(100, -5, 1))plot_ly(data, x = ~x, y = ~trace1, type = 'scatter', mode = 'lines+markers', name = 'Trace 1') %>% add_trace(y = ~trace2, mode = 'markers', name = 'Trace 2') %>% layout(title = "Combined Line and Scatter Plot", xaxis = list(title = "X"), yaxis = list(title = "Values"))
This is perfect for comparing multiple time series or data patterns on the same visualization.
Box plots summarize distributions effectively:
data(mtcars)plot_ly(mtcars, y = ~hp, type = 'box') %>% layout(title = "Horsepower Distribution in mtcars", yaxis = list(title = "HP"))
Interactive box plots allow users to explore outliers and quartiles dynamically.
Heat maps are great for visualizing matrix-style data. Using volcano:
data(volcano)plot_ly(z = ~volcano, type = 'heatmap') %>% layout(title = "Volcano Elevation Heatmap")
Hovering over cells reveals exact values, making them highly interactive for pattern analysis.
Plotly supports 3D visualizations, enhancing multidimensional data analysis:
plot_ly(iris, x = ~Sepal.Length, y = ~Sepal.Width, z = ~Petal.Length, type = 'scatter3d', mode = 'markers', color = ~Species, size = ~Petal.Width) %>% layout(title = "3D Scatterplot of Iris Dataset")
Users can rotate, zoom, and inspect points interactively, gaining insights not visible in 2D plots.
A powerful feature of Plotly is the ability to convert ggplot2 plots into interactive charts using ggplotly():
p <- ggplot(iris, aes(x = Sepal.Length, y = Petal.Length, color = Species)) + geom_point(size = 3) + theme_minimal()ggplotly(p)
This leverages ggplot2’s familiar grammar while adding interactivity like hover info, zooming, and dynamic legends.
Plotly also supports:
Example: Adding custom hover text:
plot_ly(iris, x = ~Sepal.Length, y = ~Petal.Length, color = ~Species, text = ~paste("Species:", Species, "<br>Sepal:", Sepal.Length)) %>% layout(title = "Custom Hover Text Example")
Plotly transforms R visualizations from static images into interactive, engaging, and shareable insights. From scatterplots and line charts to 3D scatter plots and heatmaps, Plotly empowers analysts to explore data dynamically and tell compelling stories. Its compatibility with ggplot2 makes it flexible for traditional users while providing advanced interactive features for dashboards and reports.
Whether you are building dashboards for internal teams, executive presentations, or public-facing insights, Plotly elevates your data from numbers to narratives.
Time to start experimenting — create your first interactive plot today and see your data come alive!
At Perceptive Analytics, our mission is “to enable businesses to unlock value in data.” For over 20 years, we’ve partnered with more than 100 clients—from Fortune 500 companies to mid-sized firms—to solve complex data analytics challenges. We provide trusted Tableau partner company in Atlanta and Tableau partner company in Austin services, helping organizations build impactful dashboards and visual analytics. Additionally, our skilled Excel consultants in Rochester deliver automation, reporting, and analytics solutions to optimize workflows. We turn data into strategic insight and would love to talk to you. Do reach out to us.