Written and maintained by CASRAI Editorial Board
Last updated
Plotly in R means the plotly package from CRAN: an R interface to the MIT-licensed plotly.js library that turns data into interactive web graphics. There are two routes to a figure. Call plot_ly() to build a plotly chart directly, or pass an existing ggplot2 figure to ggplotly() and keep the ggplot2 code you already have. This guide gives the exact commands for both, taken from the package’s own documentation, and a decision rule for choosing between them.
What it is used for in research
The package description on CRAN reads “Create interactive web graphics from ‘ggplot2’ graphs and/or a custom interface to the (MIT-licensed) JavaScript library ‘plotly.js'”. In a research workflow that gives you charts a reader can be sent as a web page instead of a fixed image, and it lets you reuse figures you already wrote in ggplot2.
plot_ly() or ggplotly()?
- You already have a ggplot2 figure: wrap it with
ggplotly(p). The plotly ggplot2 documentation shows exactly this, and the result can still be edited withlayout()andstyle(). - You are starting from the data: use
plot_ly()with the formula interface (x = ~column), as in the official getting-started example below.
If your figure is a static one for a manuscript, the CASRAI guides on scatterplots in R, histograms in R and box plots in R cover the base R and ggplot2 versions of the same charts.
Install or access (official source only)
Install the released version from CRAN:
install.packages("plotly")
The development version comes from GitHub:
devtools::install_github("ropensci/plotly")
The plotly getting-started page notes that the CRAN version “may not be the absolute latest version”, which is the reason the GitHub route exists. As checked on 2026-10-29, CRAN lists plotly 4.12.1 (published 2026-07-22) under an MIT + file LICENSE licence. It depends on R (>= 3.5.0) and ggplot2 (>= 3.0.0), and imports packages including htmlwidgets, jsonlite, httr, tidyr and dplyr. If you are new to R itself, start with how to use RStudio.
Step-by-step: your first interactive chart
Route 1: plot_ly()
- Load the package:
library(plotly) - Build the figure. The official example draws box plots of the
midwestdata set:fig <- plot_ly(midwest, x = ~percollege, color = ~state, type = "box") - Print the object:
fig
The documentation states: “Simply printing the plot object will render the chart locally in your web browser or in the RStudio viewer.”
library(plotly)
fig <- plot_ly(midwest, x = ~percollege, color = ~state, type = "box")
fig
Route 2: ggplotly() on a ggplot2 figure
- Build the ggplot2 figure and store it, here from the official example using a 1,000-row sample of
diamonds:set.seed(100) d <- diamonds[sample(nrow(diamonds), 1000), ] p <- ggplot(data = d, aes(x = carat, y = price)) + geom_point(aes(text = paste("Clarity:", clarity)), size = 4) + geom_smooth(aes(colour = cut, fill = cut)) + facet_wrap(~ cut) - Convert it:
ggplotly(p)
Note that text = paste("Clarity:", clarity) is set inside aes() in the official example, which is how extra text is attached to the points for the plotly version.
Adjusting the result
- Change the layout, for example the drag mode:
p <- ggplotly(p)thenp <- p %>% layout(dragmode = "pan") - Modify individual traces:
p %>% style(line = list(color = 'gold'), hoverinfo = "y", traces = 1) - Convert to a plotly object with
plotly_build(p), or inspect the underlying JSON withplotly_json(p).
Output and how to read it
Both routes produce an htmlwidget: a web-based object, not an image file. Printing it shows the chart in the RStudio viewer or your browser. The hoverinfo argument in the style() example above is the documented control for what the pointer display shows (here the y value), and dragmode = "pan" in layout() sets what dragging on the plot does.
Saving the figure as HTML
The plotly for R book (Carson Sievert, free online) documents saving a widget with htmlwidgets::saveWidget(). By default it “produces a completely self-contained HTML file”:
p <- plot_ly(x = 1:10, y = 1:10) %>% add_markers()
htmlwidgets::saveWidget(p, "index.html")
The book’s example reports the default file at 3.495 MB for that small chart, and 1.068 MB after wrapping it in partial_bundle(). For several figures that should share one copy of the JavaScript, it shows saveWidget(p, "p1.html", selfcontained = F, libdir = "lib"); keep the lib folder with the HTML files when you share them.
Saving a static image
Static export has its own documentation page on plotly.com/r (listed in the sources). It uses the orca() function, documented for plotly 4.7.900 and above, and requires the processx R package and a separate Orca installation; supported formats are png, jpg/jpeg, eps, svg and pdf.
Troubleshooting
Nothing appears after running plot_ly()
Assign the figure and then print the object by name (fig), as in the example. Per the documentation, printing is what renders the chart in the viewer or browser.
A feature in the documentation is missing from my install
The CRAN release may lag the development version. Check packageVersion("plotly") against the CRAN page, or install from GitHub with the command above.
ggplotly() does not give the result I expected
Convert the figure with plotly_build(p) or look at the generated structure with plotly_json(p), then fix individual traces with style(). The plotly for R book has a chapter on improving ggplotly() output.
The saved HTML file is large
Use partial_bundle(), which cut the book’s example file from 3.495 MB to 1.068 MB.
Where to look next
The book covers embedding HTML (chapter 10), exporting static images (chapter 11), arranging htmlwidgets such as in flexdashboard (chapter 13) and server-side linking with shiny (chapter 17). For documents with citations, see citations in Quarto, R Markdown and Pandoc.
Free alternatives
| Option | What it produces | Source |
|---|---|---|
| plotly package | Interactive htmlwidget charts; MIT licensed, installed from CRAN | CRAN package page |
| ggplot2 alone | Static figures; the same figure can later be wrapped with ggplotly() |
plotly ggplot2 getting-started page |
Base R graphics (plot(), hist(), boxplot()) |
Static figures; see the CASRAI guides on scatterplots, histograms and box plots in R | CASRAI guides |
FAQ
Is plotly for R free?
The R package is MIT licensed (CRAN lists “MIT + file LICENSE”) and installs from CRAN with install.packages("plotly").
Does plotly work with ggplot2?
Yes. ggplotly(p) converts a ggplot2 figure to an interactive plotly figure, and the package depends on ggplot2 (>= 3.0.0).
Do I need RStudio?
No. The documentation says printing the object renders the chart “in your web browser or in the RStudio viewer”.
What is the difference between plot_ly() and ggplotly()?
plot_ly() builds a plotly figure from data with the formula interface; ggplotly() converts a finished ggplot2 figure.
Sources (official docs, checked 2026-10-29)
- plotly R getting started: https://plotly.com/r/getting-started/ (checked 2026-10-29)
- plotly ggplot2 getting started: https://plotly.com/ggplot2/getting-started/ (checked 2026-10-29)
- CRAN package page: https://cran.r-project.org/web/packages/plotly/index.html (checked 2026-10-29)
- Static image export: https://plotly.com/r/static-image-export/ (checked 2026-10-29)
- Carson Sievert, Interactive web-based data visualization with R, plotly, and shiny: https://plotly-r.com/ (checked 2026-10-29)








