Skip to content

Commit b378735

Browse files
committed
Merge branch 'master' into gen-plotly-bundles
2 parents 0485b83 + f7acae4 commit b378735

File tree

356 files changed

+922
-553
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

356 files changed

+922
-553
lines changed

.Rbuildignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,3 +21,5 @@ README.Rmd
2121
abbvie.R
2222
^\.httr-oauth$
2323
^\.github$
24+
^\.venv$
25+
CLAUDE\.md

.github/workflows/R-CMD-check.yaml

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ jobs:
3434
- {os: ubuntu-latest, r: 'release'}
3535
- {os: ubuntu-latest, r: 'oldrel-1'}
3636
- {os: ubuntu-latest, r: 'oldrel-2'}
37-
- {os: ubuntu-latest, r: 'oldrel-3'}
37+
# - {os: ubuntu-latest, r: 'oldrel-3'} # dependency issues with oldrel-3
3838
# - {os: ubuntu-latest, r: 'oldrel-4'} # dependency issues with oldrel-4
3939

4040
env:
@@ -72,7 +72,8 @@ jobs:
7272
- name: Install kaleido
7373
if: matrix.config.visual_tests == true
7474
run: |
75-
Rscript -e 'library(reticulate); use_python(Sys.which("python")); py_install(c("kaleido", "plotly"))'
75+
# We pin kaleido to v0.2.1 here since >=v1.0 doesn't appear to be correctly rendering some plots
76+
Rscript -e 'library(reticulate); use_python(Sys.which("python")); py_install(c("kaleido==0.2.1", "plotly"))'
7677
7778
# Run test() before R CMD check since, for some reason, rcmdcheck::rcmdcheck() skips vdiffr tests
7879
- name: Run Tests

.github/workflows/docs.yml

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
# Add this file to plotly/plotly.R at .github/workflows/docs.yml
2+
#
3+
# This workflow builds and deploys the R documentation site from
4+
# the graphing-library-docs repository to this repo's GitHub Pages.
5+
6+
name: Deploy R Documentation
7+
8+
on:
9+
# Manual trigger
10+
workflow_dispatch:
11+
12+
# Run weekly to pick up any docs changes
13+
schedule:
14+
- cron: '0 0 * * 0' # Every Sunday at midnight UTC
15+
16+
# Optional: trigger from docs repo via repository_dispatch
17+
repository_dispatch:
18+
types: [docs-updated]
19+
20+
# Sets permissions for GitHub Pages deployment
21+
permissions:
22+
contents: read
23+
pages: write
24+
id-token: write
25+
26+
# Allow only one concurrent deployment
27+
concurrency:
28+
group: "pages"
29+
cancel-in-progress: false
30+
31+
env:
32+
# Change this if the docs repo moves to a different location
33+
DOCS_REPO: cpsievert/graphing-library-docs
34+
DOCS_BRANCH: master
35+
36+
jobs:
37+
build:
38+
runs-on: ubuntu-latest
39+
steps:
40+
- name: Checkout docs repository
41+
uses: actions/checkout@v4
42+
with:
43+
repository: ${{ env.DOCS_REPO }}
44+
ref: ${{ env.DOCS_BRANCH }}
45+
46+
- name: Setup Ruby
47+
uses: ruby/setup-ruby@v1
48+
with:
49+
ruby-version: '3.2'
50+
bundler-cache: true
51+
52+
- name: Fetch R/ggplot2 docs from plotly.r-docs
53+
run: make fetch
54+
55+
- name: Build site
56+
run: bundle exec jekyll build --config _config.yml,_config_production.yml
57+
env:
58+
JEKYLL_ENV: production
59+
60+
- name: Upload artifact
61+
uses: actions/upload-pages-artifact@v3
62+
with:
63+
path: _site
64+
65+
deploy:
66+
environment:
67+
name: github-pages
68+
url: ${{ steps.deployment.outputs.page_url }}
69+
runs-on: ubuntu-latest
70+
needs: build
71+
steps:
72+
- name: Deploy to GitHub Pages
73+
id: deployment
74+
uses: actions/deploy-pages@v4

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ Rapp.history
44
*.RData
55
*.Rproj.user
66
*.DS_Store
7+
.venv
78
node_modules/
89
build_site.R
910
revdep_email.R
@@ -18,3 +19,4 @@ revdep/
1819
travis_debug.R
1920
.httr-oauth
2021
tests/testthat/Rplots.pdf
22+
.venv/

CLAUDE.md

Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
# CLAUDE.md
2+
3+
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
4+
5+
## Project Overview
6+
7+
plotly is an R package for creating interactive web graphics via the plotly.js JavaScript library. It provides two main interfaces:
8+
- `ggplotly()`: Converts ggplot2 objects to interactive plotly visualizations
9+
- `plot_ly()`: Direct interface to plotly.js for specialized chart types
10+
11+
## Common Commands
12+
13+
### Running Tests
14+
```r
15+
# Run all tests
16+
devtools::test()
17+
18+
# Run visual tests (requires kaleido via reticulate)
19+
Sys.setenv("VISUAL_TESTS" = "true")
20+
devtools::test()
21+
22+
# Run a single test file
23+
devtools::test(filter = "ggplot-bar")
24+
```
25+
26+
### Package Check
27+
```r
28+
rcmdcheck::rcmdcheck()
29+
```
30+
31+
### Building Documentation
32+
```r
33+
devtools::document()
34+
```
35+
36+
### Visual Testing via Docker
37+
For consistent visual test results:
38+
```shell
39+
docker run -v $(pwd):/home/plotly --privileged -p 3838:3838 cpsievert/plotly-orca
40+
```
41+
Access the validation Shiny app at http://0.0.0.0:3838
42+
43+
CI-only visual test run:
44+
```shell
45+
docker run -e VMODE="ci" -v $(pwd):/home/plotly --privileged cpsievert/plotly-orca
46+
```
47+
48+
## Architecture
49+
50+
### ggplot2 to plotly Conversion Pipeline
51+
52+
The conversion from ggplot2 to plotly follows this flow:
53+
54+
1. **`ggplotly()`** (`R/ggplotly.R`): Entry point that dispatches on input type
55+
2. **`gg2list()`** (`R/ggplotly.R`): Main conversion function that:
56+
- Builds the ggplot object to extract computed data
57+
- Processes each layer through `layers2traces()`
58+
- Processes layout through `layers2layout()`
59+
3. **`layers2traces()`** (`R/layers2traces.R`): Converts ggplot2 geom layers to plotly trace objects
60+
4. **`layers2layout()`** (`R/layers2layout.R`): Converts ggplot2 theme/coordinate settings to plotly layout
61+
62+
### Direct plotly Interface
63+
64+
1. **`plot_ly()`** (`R/plotly.R`): Creates a plotly object with trace attributes
65+
2. **`add_trace()`** and `add_*()` functions (`R/add.R`): Add traces to existing plots
66+
3. **`layout()`** (`R/layout.R`): Modify plot layout
67+
4. **`plotly_build()`** (`R/plotly_build.R`): Evaluates lazy attributes and creates final JSON for plotly.js
68+
69+
### Key Modules
70+
71+
- `R/shiny.R`: Shiny integration and event handling
72+
- `R/subplots.R`: Combining multiple plots
73+
- `R/highlight.R`: Linked brushing/crosstalk support
74+
- `R/animate.R`: Animation support
75+
- `R/kaleido.R`, `R/orca.R`: Static image export
76+
77+
## Testing Patterns
78+
79+
Tests should check the return value of `plotly_build()`:
80+
```r
81+
test_that("example test", {
82+
p <- plot_ly(x = 1:10, y = 1:10)
83+
built <- plotly_build(p)
84+
expect_equal(built$x$data[[1]]$x, 1:10)
85+
})
86+
```
87+
88+
Visual tests use `expect_doppelganger()` from `tests/testthat/helper-vdiffr.R`:
89+
```r
90+
test_that("visual test", {
91+
p <- plot_ly(x = 1:10, y = 1:10)
92+
expect_doppelganger(p, "scatter-basic")
93+
})
94+
```
95+
96+
## Code Style
97+
98+
Follow the tidyverse style guide: http://style.tidyverse.org/

DESCRIPTION

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
Package: plotly
22
Title: Create Interactive Web Graphics via 'plotly.js'
3-
Version: 4.11.0
3+
Version: 4.12.0.9000
44
Authors@R: c(person("Carson", "Sievert", role = c("aut", "cre"),
55
email = "cpsievert1@gmail.com", comment = c(ORCID = "0000-0002-4958-2844")),
66
person("Chris", "Parmer", role = "aut",
@@ -78,7 +78,7 @@ Suggests:
7878
rsvg,
7979
ggridges
8080
LazyData: true
81-
RoxygenNote: 7.3.2
81+
RoxygenNote: 7.3.3
8282
Encoding: UTF-8
8383
Roxygen: list(markdown = TRUE)
8484
Config/Needs/check:

NAMESPACE

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ S3method(linewidth_or_size,default)
3232
S3method(linewidth_or_size,element)
3333
S3method(plotly_build,"NULL")
3434
S3method(plotly_build,gg)
35+
S3method(plotly_build,ggmatrix)
3536
S3method(plotly_build,list)
3637
S3method(plotly_build,plotly)
3738
S3method(print,api)

NEWS.md

Lines changed: 39 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,45 @@
1-
# 4.x
1+
# plotly (development version)
22

33
## Improvements
44

55
* Create the proper `bundleTraceMap` list as internal package data object directly from the upstream JS file when plotly.js is updated. As a consequence, it's now possible to use the [`strict` bundle](https://github.com/plotly/plotly.js/blob/master/dist/README.md#plotlyjs-strict) via `plotly::partial_bundle(type = "strict")`.
66

7+
# plotly 4.12.0
8+
9+
## Changes to plotly.js
10+
11+
Upgrades plotly.js from v2.11.1 to v2.25.2 (35 releases). Key new features now available:
12+
13+
* **Multiple legends**: Support for `legend2`, `legend3`, etc. with separate positioning and visibility control
14+
* **Shape labels**: New `label` attribute for shapes and `label.texttemplate` for parametric shapes
15+
* **Marker direction**: New `marker.angle`, `marker.angleref`, and `marker.standoff` properties for directional markers
16+
* **Y-axis positioning**: `shift` and `autoshift` properties to avoid y-axis overlapping in multi-axis plots
17+
* **Mapbox clustering**: Clustering options and bounds support for `scattermapbox` traces
18+
* **Equal Earth projection**: New map projection option for geo subplots
19+
* **Pattern fills**: Pattern support extended to pie, funnelarea, sunburst, icicle, and treemap charts
20+
* **Editable selections**: Persistent and editable selections over cartesian subplots with `editSelection` config option
21+
* **Axis label aliases**: `labelalias` for simplified axis label customization
22+
* **Grid styling**: `griddash` property and minor tick/grid line styling options
23+
24+
Also includes a security fix for prototype pollution and ~90KB bundle size reduction.
25+
26+
See the [plotly.js releases page](https://github.com/plotly/plotly.js/releases) for the full changelog.
27+
28+
## Improvements
29+
30+
* `save_image()` now works with kaleido v1.0 and higher. (#2447)
31+
32+
## Bug fixes
33+
34+
* `plotly_build()` now works with `ggmatrix` objects (e.g., from `GGally::ggpairs()`). (#2447)
35+
* Closed #2415: `ggplotly()` now shows variables named 'group' in tooltips when mapped to aesthetics like `colour`.
36+
* Closed #2455, #2460: `ggplotly()` no longer creates empty shapes when `panel.border` is `element_blank()` (ggplot2 4.0.0 compatibility).
37+
* Closed #2466: `ggplotly()` no longer errors when `scale_*_manual()` has unused aesthetics (e.g., `aesthetics = c("colour", "fill")` when only colour is used).
38+
* Closed #2305: `ggplotly()` now respects `geom_boxplot(outlier.shape = NA)` to hide outlier points.
39+
* Closed #2467: `ggplotly()` now correctly shows legends and splits traces when scales have multiple aesthetics.
40+
* Closed #2407, #2187: `ggplotly()` now translates `legend.position` theme element to plotly layout (supports "bottom", "top", "left", and numeric positions).
41+
* Closed #2281: `ggplotly()` no longer drops legends when `geom_blank()` is present in the plot.
42+
743
# plotly 4.11.0
844

945
## New features
@@ -375,7 +411,7 @@ This is minor patch release with a few minor bug fixes and updates test expectat
375411
* Added the `highlight()` function for configuring selection modes/sequences/options.
376412
* Added support for animation. For some relatively basic examples, see the examples section of `help(animation)`. For a more thorough overview, see <https://plotly-r.com/animating-views.html>
377413
* Added a `frame` argument to `plot_ly()` for creating animations. Also added the `animation_opts()`, `animation_slider()`, and `animation_button()` functions for configuring animation defaults.
378-
* Added a new interface to [v2 of the REST API](https://api.plot.ly/v2). This new interface makes the `plotly_POST()` and `get_figure()` functions obsolete (use `api_create()` and `api_download_plot()` instead), and thus, are now deprecated, but remain around for backwards-compatibility. For more details, see `help(api)`.
414+
* Added a new interface to v2 of the REST API. This new interface makes the `plotly_POST()` and `get_figure()` functions obsolete (use `api_create()` and `api_download_plot()` instead), and thus, are now deprecated, but remain around for backwards-compatibility. For more details, see `help(api)`.
379415
* Added support for conversion of more **ggplot2** geoms via `ggplotly()`: `GeomCol`, `GeomRug`, `GeomCrossbar`, `GeomQuantile`, `GeomSpoke`, `GeomDotplot`, `GeomRasterAnn` (i.e., `annotation_raster()`), and `GeomAnnotationMap` (i.e., `annotation_map()`).
380416
* Added a new function `raster2uri()` which makes it easier to embed raster objects as [images](https://plotly.com/r/reference/#layout-images) via data URIs. For examples, see `help(raster2uri)`.
381417
* `ggplotly()` gains a new argument, `dynamicTicks`, which allows axis ticks to update upon zoom/pan interactions (fixes #485).
@@ -1152,7 +1188,7 @@ Fixed filename, fileopt arguments in plot_ly. Specifying the same filename will
11521188

11531189
1.0.8 -- 14 Sep 2015
11541190

1155-
Added the plotly_IMAGES() function which interfaces to the images endpoint https://api.plot.ly/v2/#images
1191+
Added the plotly_IMAGES() function which interfaces to the images endpoint.
11561192

11571193
Details -> https://github.com/ropensci/plotly/pull/279
11581194

R/api_exports.R

Lines changed: 10 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,6 @@
4444
#' @export
4545
#' @rdname api
4646
#' @author Carson Sievert
47-
#' @references \url{https://api.plot.ly/v2}
4847
#' @seealso [signup()]
4948
#' @examplesIf interactive() || !identical(.Platform$OS.type, "windows")
5049
#'
@@ -80,30 +79,29 @@
8079
#' api()
8180
#'
8281
#' # search the entire platform!
83-
#' # see https://api.plot.ly/v2/search
8482
#' api("search?q=overdose")
8583
#' api("search?q=plottype:pie trump fake")
8684
#'
8785
#' # these examples will require a user account
8886
#' usr <- Sys.getenv("plotly_username", NA)
8987
#' if (!is.na(usr)) {
90-
#' # your account info https://api.plot.ly/v2/#users
88+
#' # your account info
9189
#' api(sprintf("users/%s", usr))
92-
#' # your folders/files https://api.plot.ly/v2/folders#user
90+
#' # your folders/files
9391
#' api(sprintf("folders/home?user=%s", usr))
9492
#' }
9593
#'
96-
#' # Retrieve a specific file https://api.plot.ly/v2/files#retrieve
94+
#' # Retrieve a specific file
9795
#' api("files/cpsievert:14681")
98-
#'
99-
#' # change the filename https://api.plot.ly/v2/files#update
96+
#'
97+
#' # change the filename
10098
#' # (note: this won't work unless you have proper credentials to the relevant account)
101-
#' api("files/cpsievert:14681", "PATCH", list(filename = "toy file"))
102-
#'
103-
#' # Copy a file https://api.plot.ly/v2/files#lookup
99+
#' api("files/cpsievert:14681", "PATCH", list(filename = "toy file"))
100+
#'
101+
#' # Copy a file
104102
#' api("files/cpsievert:14681/copy", "POST")
105-
#'
106-
#' # Create a folder https://api.plot.ly/v2/folders#create
103+
#'
104+
#' # Create a folder
107105
#' api("folders", "POST", list(path = "/starts/at/root/and/ends/here"))
108106
#'
109107
#' }

0 commit comments

Comments
 (0)