diff --git a/DESCRIPTION b/DESCRIPTION index 6f236da3ad..07827bc830 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -1,88 +1,89 @@ -Package: plotly -Title: Create Interactive Web Graphics via 'plotly.js' -Version: 4.10.2.9000 -Authors@R: c(person("Carson", "Sievert", role = c("aut", "cre"), - email = "cpsievert1@gmail.com", comment = c(ORCID = "0000-0002-4958-2844")), - person("Chris", "Parmer", role = "aut", - email = "chris@plot.ly"), - person("Toby", "Hocking", role = "aut", - email = "tdhock5@gmail.com"), - person("Scott", "Chamberlain", role = "aut", - email = "myrmecocystus@gmail.com"), - person("Karthik", "Ram", role = "aut", - email = "karthik.ram@gmail.com"), - person("Marianne", "Corvellec", role = "aut", - email = "marianne.corvellec@igdore.org", comment = c(ORCID = "0000-0002-1994-3581")), - person("Pedro", "Despouy", role = "aut", - email = "pedro@plot.ly"), - person("Salim", "Brüggemann", role = "ctb", - email = "salim-b@pm.me", comment = c(ORCID = "0000-0002-5329-5987")), - person("Plotly Technologies Inc.", role = "cph")) -License: MIT + file LICENSE -Description: Create interactive web graphics from 'ggplot2' graphs and/or a custom interface to the (MIT-licensed) JavaScript library 'plotly.js' inspired by the grammar of graphics. -URL: https://plotly-r.com, https://github.com/plotly/plotly.R, https://plotly.com/r/ -BugReports: https://github.com/plotly/plotly.R/issues -Depends: - R (>= 3.2.0), - ggplot2 (>= 3.0.0) -Imports: - tools, - scales, - httr (>= 1.3.0), - jsonlite (>= 1.6), - magrittr, - digest, - viridisLite, - base64enc, - htmltools (>= 0.3.6), - htmlwidgets (>= 1.5.2.9001), - tidyr (>= 1.0.0), - RColorBrewer, - dplyr, - vctrs, - tibble, - lazyeval (>= 0.2.0), - rlang (>= 0.4.10), - crosstalk, - purrr, - data.table, - promises -Suggests: - MASS, - maps, - hexbin, - ggthemes, - GGally, - ggalluvial, - testthat, - knitr, - shiny (>= 1.1.0), - shinytest (>= 1.3.0), - curl, - rmarkdown, - Cairo, - broom, - webshot, - listviewer, - dendextend, - maptools, - rgeos, - sf, - png, - IRdisplay, - processx, - plotlyGeoAssets, - forcats, - palmerpenguins, - rversions, - reticulate, - rsvg -LazyData: true -RoxygenNote: 7.2.3 -Encoding: UTF-8 -Roxygen: list(markdown = TRUE) -Config/Needs/check: - tidyverse/ggplot2, - rcmdcheck, - devtools, - reshape2 +Package: plotly +Title: Create Interactive Web Graphics via 'plotly.js' +Version: 4.10.2.9000 +Authors@R: c(person("Carson", "Sievert", role = c("aut", "cre"), + email = "cpsievert1@gmail.com", comment = c(ORCID = "0000-0002-4958-2844")), + person("Chris", "Parmer", role = "aut", + email = "chris@plot.ly"), + person("Toby", "Hocking", role = "aut", + email = "tdhock5@gmail.com"), + person("Scott", "Chamberlain", role = "aut", + email = "myrmecocystus@gmail.com"), + person("Karthik", "Ram", role = "aut", + email = "karthik.ram@gmail.com"), + person("Marianne", "Corvellec", role = "aut", + email = "marianne.corvellec@igdore.org", comment = c(ORCID = "0000-0002-1994-3581")), + person("Pedro", "Despouy", role = "aut", + email = "pedro@plot.ly"), + person("Salim", "Brüggemann", role = "ctb", + email = "salim-b@pm.me", comment = c(ORCID = "0000-0002-5329-5987")), + person("Plotly Technologies Inc.", role = "cph"), + person("William", "Holmes", role = c("ctb"))) +License: MIT + file LICENSE +Description: Create interactive web graphics from 'ggplot2' graphs and/or a custom interface to the (MIT-licensed) JavaScript library 'plotly.js' inspired by the grammar of graphics. +URL: https://plotly-r.com, https://github.com/plotly/plotly.R, https://plotly.com/r/ +BugReports: https://github.com/plotly/plotly.R/issues +Depends: + R (>= 3.2.0), + ggplot2 (>= 3.0.0) +Imports: + tools, + scales, + httr (>= 1.3.0), + jsonlite (>= 1.6), + magrittr, + digest, + viridisLite, + base64enc, + htmltools (>= 0.3.6), + htmlwidgets (>= 1.5.2.9001), + tidyr (>= 1.0.0), + RColorBrewer, + dplyr, + vctrs, + tibble, + lazyeval (>= 0.2.0), + rlang (>= 0.4.10), + crosstalk, + purrr, + data.table, + promises +Suggests: + MASS, + maps, + hexbin, + ggthemes, + GGally, + ggalluvial, + testthat, + knitr, + shiny (>= 1.1.0), + shinytest (>= 1.3.0), + curl, + rmarkdown, + Cairo, + broom, + webshot, + listviewer, + dendextend, + maptools, + rgeos, + sf, + png, + IRdisplay, + processx, + plotlyGeoAssets, + forcats, + palmerpenguins, + rversions, + reticulate, + rsvg +LazyData: true +RoxygenNote: 7.2.3 +Encoding: UTF-8 +Roxygen: list(markdown = TRUE) +Config/Needs/check: + tidyverse/ggplot2, + rcmdcheck, + devtools, + reshape2 diff --git a/NAMESPACE b/NAMESPACE index 9fe5f8e0d5..f6dc929d82 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -170,6 +170,7 @@ export(plotly_data) export(plotly_empty) export(plotly_example) export(plotly_json) +export(plotly_merge) export(rangeslider) export(raster2uri) export(remove_typedarray_polyfill) diff --git a/NEWS.md b/NEWS.md index 91e0074afd..62bc63e246 100644 --- a/NEWS.md +++ b/NEWS.md @@ -1,1331 +1,1335 @@ -# 4.10.2.9000 - -## Bug fixes - -* Closed #1947: `ggplotly()` now correctly handles `geom_vline`/`geom_hline` with empty data. Previously, if `geom_vline`/`geom_hline` was passed an empty data frame, it would result in an error. The plot is drawn even if no lines are found; this is the same behavior as `ggplot2`. - -# 4.10.2 - -## New features - -* Closed #2216: Additional selectize.js options can now be passed along to `highlight()`'s `selectize` argument. (#2217) - -## Improvements - -* Closed #2259: `ggplotly()` now provides better support for ggplot2 >v3.4.2. (#2262) - -## Bug fixes - -* Closed #2212: `ggplotly()` no longer silently drops legends that are customized through `ggplot2::guide_legend()`. -* Closed #2179: `save_image()` no longer needs `reticulate::py_run_string("import sys")` in order to run without error. (#2179) -* Closed #2218: `highlight(selectize = TRUE)` no longer yields an incorrect selectize.js result when there is a combination of crosstalk and non-crosstalk traces. (#2217) -* Closed #2208: `ggplotly()` no longer errors given a `geom_area()` with 1 or less data points (error introduced by new behavior in ggplot2 v3.4.0). (#2209) -* Closed #2220: `ggplotly()` no longer errors on `stat_summary(geom = "crossbar")`. (#2222) -* Closed #2212: `ggplotly()` no longer removes legends when setting guide properties via `guides(aes = guide_xxx(...))`. - -# 4.10.1 - -## Changes to plotly.js - -* This version of the R package upgrades the version of the underlying plotly.js library from v2.5.1 to v2.11.1. This includes many bug fixes and improvements. The [plotly.js release page](https://github.com/plotly/plotly.js/releases) has the full list of changes. - -## New features - -* `plotlyOutput()` gains a new `fill` parameter. When `TRUE` (the default), the widget's container element is allowed to grow/shrink to fit it's parent container so long as that parent is opinionated about its height and has been marked with `htmltools::bindFillRole(x, container = TRUE)`. (#2198) - * The primary motivation for this is to allow plots to grow/shrink by default [inside `bslib::card_body_fill()`](https://rstudio.github.io/bslib/articles/cards.html#responsive-sizing) -* `ggplotly()` now supports the `{ggalluvial}` package. (#2061, thanks @moutikabdessabour) -* `highlight()` now supports `on="plotly_selecting"`, enabling client-side linked brushing via mouse click+drag (no mouse-up event required, as with `on="plotly_selected"`). (#1280) -* `raster2uri()` supports nativeRaster objects. This enables nativeRaster support for - the `annotation_raster()` geom (#2174, @zeehio). - -## Bug fixes - -* `ggplotly()` now converts `stat_ecdf()` properly. (#2065) -* `ggplotly()` now correctly handles `geom_tile()` with no `fill` aesthetic. (#2063) -* `ggplotly()` now respects `guide(aes = "none")` (e.g., `guide(fill = "none")`) when constructing legend entries. (#2067) -* Fixed an issue with translating `GGally::ggcorr()` via `ggplotly()`. (#2012) -* Fixed an issue where clearing a crosstalk filter would raise an error in the JS console (#2087) -* Fixed an issue where `map_color()` would throw an error on R 4.2 (#2131) - -## Improvements - -* `ggplotly()` does not issue warnings with `options(warnPartialMatchArgs = TRUE)` any longer. (#2046, thanks @bersbersbers) -* `ggplotly()` does not issue warnings related to use of deprecated `tidyr::gather_()` in internals. (#2125, thanks @simonpcouch) - -# 4.10.0 - -## Breaking changes in JavaScript API - -* This version of the R package upgrades the version of the underlying plotly.js library from v1.57.1 to v2.5.1. This includes many breaking changes, bug fixes, and improvements to the underlying JavaScript library. Most of the breaking changes are summarized in [this announcement of the 2.0 release](https://community.plotly.com/t/announcing-plotly-js-2-0/53675), but [see here](https://github.com/plotly/plotly.js/blob/HEAD/CHANGELOG.md) for the full changelog. - -## Breaking changes in R API - -* `ggplotly()` now uses the `layout.legend.title` (instead of `layout.annotations`) plotly.js API to convert guides for discrete scales. (#1961) -* `renderPlotly()` now uses `Plotly.react()` (instead of `Plotly.newPlot()`) to redraw when `layout(transition = )` is specified. This makes it possible/easier to implement a smooth transitions when `renderPlotly()` gets re-executed. (#2001) - -## New Features - -* Added new functions for static image exporting via the [kaleido python package](https://github.com/plotly/Kaleido), namely `save_image()` and `kaleido()`. See `help(save_image, package = "plotly")` for installation info and example usage. (#1971) - -## Improvements - -* `ggplotly()` now better positions axis titles for `facet_wrap()`/`facet_grid()`. (#1975) - -# 4.9.4.1 - -## BUG FIXES - -* Fixes a bug in `ggplotly()` with `{crosstalk}` and `{ggplot2}` v3.3.4 (#1952). - -# 4.9.4 - -## BUG FIXES - -* Duplicate `highlight(selectize=T)` dropdowns are no longer rendered in Shiny (#1936). -* `group_by.plotly()` now properly retains crosstalk information across `{dplyr}` versions (#1920). -* Adds fixes in `ggplotly()` for the upcoming `{ggplot2}` v3.3.4 release (#1952). -* Fixes some issues with `name` and `frames` when both attributes are specified. (#1903 and #1618). - -# 4.9.3 - -## Changes to plotly.js - -* This version of the R package upgrades the version of the underlying plotly.js library from v1.52.2 to v1.57.1. This includes many bug fixes and improvements. The [plotly.js release page](https://github.com/plotly/plotly.js/releases) has the full list of changes. - -## NEW FEATURES - -* `renderPlotly()` now works well with `shiny::bindCache()`, meaning that plotly graphs can now be persistently cached in Shiny apps with `renderPlotly(expr) %>% shiny::bindCache()` (#1879). - -* `ggplotly()` now works well with the [**thematic** package](https://rstudio.github.io/thematic/). That is, it can now correctly translate **ggplot2** styling that derives from **thematic**. Note that, in order to use **thematic**'s auto theming in Shiny with `ggplotly()`, you need **shiny** v1.5.0 (or higher) and **htmlwidgets** v1.5.2.9000 (or higher). Relatedly, if these versions are available, one may now also call `getCurrentOutputInfo()` inside `renderPlotly()` to get CSS styles of the output container (#1801 and #1802). - -## IMPROVEMENTS - -* All HTTP requests are now retried upon failure (#1656, @jameslamb). - -* R linebreaks (`\n`) in _factor labels_ are now translated to HTML linebreaks (`
`), too. Before, this conversion was only done for colums of type character. ([#1700](https://github.com/plotly/plotly.R/pull/1700), @salim-b). - -## BUG FIXES - -* When R's `POSIXt` class is serialized to JSON, the time of day is now correctly preserved (in plotly.js expected `'yyyy-mm-dd HH:MM:SS.ssssss'` format). This should fix a whole host of issues where date-times were being rounded. (#1871, @FlukeAndFeather). - -* `ggplotly()` now handles discrete axes of a `facet_wrap` and `facet_grid` correctly when there is only one category in panels > 1 (#1577 and #1720). - -* `ggplotly()` now correctly accounts for linebreaks in tick label text when computing plot margins (#1791, @trekonom). - -* `ggplotly()` now handles `element_blank()` and `factor()` labels in positional scales correctly (#1731 and #1772). - -* `ggplotly()` now handles missing `y` aesthetic in `geom_errorbar()` (#1779, @trekonom). - -# 4.9.2.1 - -This is minor patch release with a few minor bug fixes and updates test expectations in anticipation of new R 4.0 defaults. - -## BUG FIXES - -* Fixes rendering issues non-HTML **rmarkdown** output formats, which was introduced in the 4.9.2 release (#1702). -* Fixes a `ggplotly()` bug in axis tick translation (#1725, #1721). -* `plot_mapbox()` now correctly defaults to a scattermapbox trace (unless z is present, then it defaults to choroplethmapbox) (#1707). -* `ggplotly()` now correctly resolves overlapping axis tick text in `coord_sf()` (#1673). -* A false-positive warning is no longer thrown when attempting to cast `toWebGL()` (#1569). - -# 4.9.2 - -## Changes to plotly.js - -* This version of the R package upgrades the version of the underlying plotly.js library from v1.49.4 to v1.52.2. This includes many bug fixes, improvements, as well as 2 new trace types: `treemap` and `image`. The [plotly.js release page](https://github.com/plotly/plotly.js/releases) has the full list of changes. - -## IMPROVEMENTS - -* The `add_image()` function was added to make it easier to create image traces via `raster` objects. - -## BUG FIXES - -* `add_sf()`/`geom_sf()` now correctly handle geometry columns that are named something other than `"geometry"` (#1659). -* Specifying an english locale no longer results in error (#1686). - -# 4.9.1 - -## Changes to plotly.js - -* This version of the R package upgrades the version of the underlying plotly.js library from v1.46.1 to v1.49.4. The [plotly.js release page](https://github.com/plotly/plotly.js/releases) has the full list of changes. - -## IMPROVEMENTS - -* `event_data()` gains support for the `plotly_sunburstclick` event (#1648) - -## BUG FIXES - -* Fixed an issue with correctly capturing the return value of user-expressions to `renderPlotly()` (#1528). -* Fixed a resizing issue where graphs could be incorrectly resized to their initial size in some cases (#1553). -* `ggplotly()` now positions the x-axis in the last column of a `facet_wrap()` properly (#1501). -* `ggplotly()` now handles `geom_hline()`/`geom_vline()` correctly in conjunction with `coord_flip()` (#1519). -* `event_data()` now correctly relays the `key` attribute for statistical traces (#1610). - -# 4.9.0 - -## Changes to plotly.js - -* This version of the R package upgrades the version of the underlying plotly.js library from v1.42.3 to v1.46.1. The [plotly.js release page](https://github.com/plotly/plotly.js/releases) has the full list of changes, but here is summary most pertainent ones for the R package: - * New trace types: `sunburst`, `waterfall`, `isosurface`. - * New `hovertemplate` attribute allows for finer-tuned control over tooltip text. See [here](https://plotly-r.com/controlling-tooltips.html#fig:tooltip-format-heatmap) for an example. - * Providing a string to `title` is now deprecated (but still works). Instead, use `title = list(text = "title")`. This change was made to support a new title placement API (e.g., `title = list(text = "title", xanchor = "left")`). Note that these changes are relevant for `layout.title` as well as `layout.xaxis.title`/`layout.yaxis.title`/etc. - -## NEW FEATURES & IMPROVEMENTS - -* Several new features and improvements related to accessing plotly.js events in shiny (learn more about them in this RStudio [webinar](https://posit.co/resources/videos/accessing-and-responding-to-plotly-events-in-shiny/)): - * The `event` argument of the `event_data()` function now supports the following events: `plotly_selecting`, `plotly_brushed`, `plotly_brushing`, `plotly_restyle`, `plotly_legendclick`, `plotly_legenddoubleclick`, `plotly_clickannotation`, `plotly_afterplot`, `plotly_doubleclick`, `plotly_deselect`, `plotly_unhover`. For examples, see `plotly_example("shiny", "event_data")`, `plotly_example("shiny", "event_data_legends")`, and `plotly_example("shiny", "event_data_annotation")`, - * New `event_register()` and `event_unregister()` functions for declaring which events to transmit over the wire (i.e., from the browser to the shiny server). Events that are likely to have large overhead are not registered by default, so you'll need to register these: `plotly_selecting`, `plotly_unhover`, `plotly_restyle`, `plotly_legendclick`, and `plotly_legenddoubleclick`. - * A new `priority` argument. By setting `priority='event'`, the `event` is treated like a true event: any reactive expression using the `event` becomes invalidated (regardless of whether the input values has changed). For an example, see `plotly_example("shiny", "event_priority")`. - * The `event_data()` function now relays the (official plotly.js) `customdata` attribute in similar fashion to (unofficial) `key` attribute (#1423). Run `plotly_example("shiny", "event_data")` for an example. - * `event_data("plotly_selected")` is no longer too eager to clear. That is, it is no longer set to `NULL` when clicking on a plot *after* triggering the "plotly_selected" event (#1121) (#1122). - -* Several new features and improvements for exporting static graphs with the orca command-line utility: - * The `orca()` function now supports conversion of much larger figures (#1322) and works without a mapbox api token (#1314). - * The `orca_serve()` function was added for efficient exporting of many plotly graphs. For examples, see `help(orca_serve)`. - * The `orca()` function gains new arguments `more_args` and `...` for finer control over the underlying system commands. - -* `ggplotly()` now respects horizontal alignment of **ggplot2** titles (e.g., `ggplotly(qplot(1:10) + ggtitle("A title") + theme(plot.title = element_text(hjust = 1)))`). -* **plotly** objects can now be serialized and unserialized in different environments (i.e., you can now use `saveRDS()` to save an object as an rds file and restore it on another machine with `readRDS()`). Note this object is *dynamically* linked to JavaScript libraries, so one should take care to use consistent versions of **plotly** when serializing and unserializing (#1376). -* The `style()` function now supports "partial updates" (i.e. modification of a particular property of an object, rather than the entire object). For example, notice how the first plot retains the original marker shape (a square): `p <- plot_ly(x = 1:10, y = 1:10, symbol = I(15)); subplot(style(p, marker.color = "red"), style(p, marker = list(color = "red")))` (#1342). -* The `method` argument of `plotlyProxyInvoke()` gains support for a `"reconfig"` method. This makes it possible to modify just the configuration of a plot in a **shiny** app. For an example use, see `plotly_example("shiny", "event_data_annotation")`. -* The `plotly_example()` function will now attempt to open the source file(s) used to run the example. Set `edit = FALSE` to prevent the source file(s) from opening. -* An informative warning is now thrown if invalid argument names are supplied to `config()`. - -## CHANGES - -* If `stroke` is specified, `span` now defaults to `I(1)`. This results in a slightly narrower default span for some trace types (e.g., `box`, `contour`), but it also ensures the `stroke` is always visible when it's relevant (e.g. `plot_ly(x = 1:10, y = 1:10, stroke = I("black"))`), making for a more consistent overall default (#1507). -* The 'collaborate' button no longer appears in the modebar, and is longer supported, so the `config()` function no longer has a `collaborate` argument. -* The `cloud` argument is now deprecated and will be removed in a future version. Use `showSendToCloud` instead. -* `ggplotly()` now translates title information to `layout.title.text` (instead of `layout.title`) and `layout.title.font` (instead of `layout.titlefont`) - -## BUG FIXES - -* `subplot()` now works much better with annotations, images, and shapes: - - When `xref`/`yref` references an x/y axis these references are bumped accordingly (#1181). - - When `xref`/`yref` references paper coordinates, these coordinates are updated accordingly (#1332). -* `subplot()` now repositions shapes with fixed height/width (i.e., `xsizemode`/`ysizemode` of `"pixel"`) correctly (#1494). -* The `colorscale` attribute now correctly handles a wider range of input values (#1432, #1485) -* The colorscale generated via the `color` argument in `plot_ly()` now uses an evenly spaced grid of values instead of quantiles (#1308). -* When using **shinytest** to test a **shiny** that contains **plotly** graph, false positive differences are no longer reported (rstudio/shinytest#174). -* When the `size` argument maps to `marker.size`, it now converts to an array of appropriate length (#1479). -* The `color` and `stroke` arguments now work as expected for trace types with `fillcolor` but no `fill` attribute (e.g. `box` traces) (#1292). -* Information emitted by in `event_data()` for heatmaps with atomic vectors for `x`/`y`/`z` is now correct (#1141). -* Fixed issue where **dplyr** groups caused a problem in the ordering of data arrays passed to `marker` objects (#1351). -* In some cases, a `ggplotly()` colorbar would cause issues with hover behavior, which is now fixed (#1381). -* An articial marker no longer appears when clearing a crosstalk selection of a plot with a colorbar (#1406). -* Clearing a highlight event via crosstalk no longer deletes all the traces added since initial draw (#1436). -* Recursive attribute validation is now only performed on recursive objects (#1315). -* The `text` attribute is no longer collapsed to a string when `hoveron='fills+points'` (#1448). -* `layout.[x-y]axis.domain` is no longer supplied a default when `layout.grid` is specified (#1427). -* When uploading charts to a plot.ly account via `api_create()`, layout attributes are no longer incorrectly src-ified, which was causing inconsistencies in local/remote rendering of `ggplotly()` charts (#1197). - -# 4.8.0 - -## NEW FEATURES & IMPROVEMENTS - -### plotly.js and `plot_ly()` specific improvements - -* Upgraded to plotly.js v1.39.2. A _huge_ amount of features and improvements have been made since v1.29.2 (i.e., the version included in the last CRAN release of the R package - v4.7.1). Highlights include a complete re-write of `scattergl` to make it nearly feature complete with `scatter`, localization of text rendering (i.e., international translations), and six new trace types (`cone`, `scatterpolar`, `scatterpolargl`, `splom`, `table`, & `violin`)! See [here](https://github.com/plotly/plotly.js/releases) for a complete list of plotly.js-specific improvements. -* Support for **sf** (simple feature) data structures was added to `plot_ly()`, `plot_mapbox()`, and `plot_geo()` (via the new `add_sf()` function). See [this blog post](https://blog.cpsievert.me/2018/03/30/visualizing-geo-spatial-data-with-sf-and-plotly) for an overview. -* Better control over the stroke (i.e., outline) appearance of various filled graphical marks via the new "special arguments" (`stroke`, `strokes`, `alpha_stroke`, `span`, and `spans`). For an overview, see the **sf** blog post linked to in the bullet point above and the new package demos (list all demos with `demo(package = "plotly")`). - -### `ggplotly()` specific improvements - -* `ggplotly()` now supports conversion of **ggplot2**'s `geom_sf()`. -* One may now inform `ggplotly()` about the relevant **shiny** output size via `session$clientData`. This ensures `ggplotly()` sizing is closer to **ggplot2** sizing, even on window resize. For an example, run `plotly_example("shiny", "ggplotly_sizing")`. - -### Other improvements relevant for all **plotly** objects - -* LaTeX rendering via MathJax is now supported and the new `TeX()` function may be used to flag a character vector as LaTeX (#375). Use the new `mathjax` argument in `config()` to specify either external (`mathjax="cdn"`) or local (`mathjax="local"`) MathJaX. If `"cdn"`, mathjax is loaded externally (meaning an internet connection is needed for TeX rendering). If `"local"`, the PLOTLY_MATHJAX_PATH environment variable must be set to the location (a local file path) of MathJax. IMPORTANT: **plotly** uses SVG-based mathjax rendering which doesn't play nicely with HTML-based rendering (e.g., **rmarkdown** documents and **shiny** apps). To leverage both types of rendering, you must `