Introduction to Interactive Graphics in R with plotly

Michael Battaglia

Posted on
rstats plotly data visualization

R users adore the ggplot2 package for all things data visualization. Its consistent syntax, useful defaults, and flexibility make it a fantastic tool for creating high-quality figures. Although ggplot2 is great, there are other dataviz tools that deserve a place in a data scientist’s toolbox. Enter plotly.

plotly is a high-level interface to plotly.js, based on d3.js which provides an easy-to-use UI to generate slick D3 interactive graphics. These interactive graphs give the user the ability to zoom the plot in and out, hover over a point to get additional information, filter to groups of points, and much more. These interactive components contribute to an engaging user experience and allows information to be displayed in ways that are not possible with static figures.

The wonder of htmlwidgets

As you may have guessed, the “.js” in plotly.js is short for JavaScript. JavaScript is a programming language that runs a majority of the Internet’s interactive webpages. To make a webpage interactive, JavaScript code is embedded into HTML which is run by the user’s web browser. As the user interacts with the page, the JavaScript renders new HTML, providing the interactive experience that we are looking for. htmlwidgets is the framework that allows for the creation of R bindings to JavaScript libraries. These JavaScript visualizations can be embedded into R Markdown documents (html) or shiny apps.

Here are a few examples of JavaScript bindings in R:
- plotly
- highcharter
- diagrammeR
- leaflet


There are two main approaches to initialize a plotly object: transforming a ggplot2 object with ggplotly() or setting up aesthetics mappings with plot_ly() directly.


ggplotly() takes existing ggplot2 objects and converts them into interactive plotly graphics. This makes it easy to create interactive figures while using the ggplot2 syntax that we’re already used to. Additionally, ggplotly() allows us to use ggplot2 functionality that would not be as easily replicated with plotly and tap into the wide range of ggplot2 extension packages.

Let’s look at an example using the mpg dataset from ggplot2.


(ggplot_object <- mpg %>%
  ggplot(aes(x = displ, y = hwy)) + 
  geom_point(mapping = aes(color = class)) + 


After saving a ggplot2 object, the only step to plotly-ize it is calling ggplotly() on that object.

The difference between the two is that the plotly figure is interactive. Try it out for yourself! Some of the interactive features to try out include hovering over a point to see the exact x and y values, zooming in by selecting (click+drag) a region, and subsetting to specific groups by clicking their names in the legend.


plot_ly() is the base plotly command to initialize a plot from a dataframe, similar to ggplot() from ggplot2.

mpg %>%
  plot_ly(x = ~displ, y = ~hwy, color = ~class)
## No trace type specified:
##   Based on info supplied, a 'scatter' trace seems appropriate.
##   Read more about this trace type ->
## No scatter mode specifed:
##   Setting the mode to markers
##   Read more about this attribute ->

Although we did not specify the plot type, it defaulted to a scatter plot. The type of plot is specified by setting the trace type. The scatter trace type is the foundation for many low-level geometries (e.g., points, lines, and text), thus we must also specify a mode. To create a scatter plot with points the mode is set to markers, but additional scatter modes include lines, paths, segments, ribbons, polygons, and text.

plotly functions take a plotly object as an input and return a modified plotly object, making it work perfectly with the pipe (%>%).

mpg %>%
  plot_ly(x = ~displ, y = ~hwy, color = ~class) %>%
  add_trace(type = "scatter", mode = "markers")


Rather than using add_trace() and specifying the type and mode, we can use the convenience function add_markers().

mpg %>%
  plot_ly(x = ~displ, y = ~hwy, color = ~class) %>%

Making other plot types is similarly easy by using the corresponding add_*() function. See the documentation for a full list of traces:


I was never taught about interactive graphics in school and never felt the need to learn it, but now I find uses for it all the time. Whether you are making a shiny app or just writing a statistical report I recommend trying out plotly. There is not much of a learning curve due to the intuitive syntax, and it makes high quality graphics that are sure to impress. This post only scratches the surface of plotly, but I hope this introduction gives you more confidence to try it out in your future work.