19.7 Output arguments for render functions

In a typical Shiny application, you specify an output element in the UI using functions like plotOutput() and verbatimTextOutput(), and render its content using functions like renderPlot() and renderPrint().

By comparison, in a Shiny document, the UI elements are often implicitly and automatically created when you call the renderXXX() functions. For example, you may want to use a renderPlot() function without having to create a plotOutput() slot beforehand. In this case, Shiny helpfully associates the corresponding output object to each renderXXX() function, letting you use Shiny code outside of a full Shiny app. However, some functionality can be lost in this process. In particular, plotOutput() can take in some optional arguments to set things like width and height, or allow you to click or brush over the plot (and store that information).

To pass options from renderXXX() to xxxOutput(), you can use the outputArgs argument, if it is available to specific renderXXX() functions. For example, suppose that you want to render a plot and specify its width to be 200px and height to be 100px. Then you should use:

```{r, echo = FALSE}
renderPlot({
  plot(yourData)
}, outputArgs = list(width = "200px", height = "100px")
)
```

No matter how many output arguments you want to set (all the way from zero to all possible ones), outputArgs always takes in a list (the default is an empty list, which sets no output arguments). If you try to pass in a non-existent argument, you will get an error like the following message (in this example, you tried to set an argument named not_an_argument):

**Error**: Unused argument: in `outputArgs`, `not_an_argument`
is not an valid argument for the output function

To see outputArgs in action, run the R Markdown document below or visit https://gallery.shinyapps.io/output-args/ for the live version online. The document is interactive: brush over the image and see the xmin, xmax, ymin, and ymax values change (printed right under the image).

---
title: Setting output args via render functions
runtime: shiny
output: html_document
---

This interactive Rmd document makes use of the `outputArgs`
argument now available to all Shiny `render` functions. To
give an example, this allows you to set arguments to
`imageOutput` through `renderImage`. This means that you
don't have to create a `ui` object just to be able to brush
over an image. Note that this only applies to snippets of
Shiny code during an interactive Rmd (and not to embedded
full apps -- the ones you need to call `shinyApp` to run).

## Brushing over an image (and storing the data)

```{r setup, echo=FALSE}
library(datasets)

generateImage = function() {
  outfile = tempfile(fileext = '.png')
  png(outfile)
  par(mar = c(0,0,0,0))
  image(volcano, axes = FALSE)
  contour(volcano, add = TRUE)
  dev.off()
  list(src = outfile)
}
```

```{r image}
renderImage({
  generateImage()
}, deleteFile = TRUE, 
   outputArgs = list(brush = brushOpts(id = "plot_brush"),
                     width = "250",
                     height = "250px")
)
```

Here is some of the brushing info sent to the server:
(brush over the image to change the data)

```{r brush info}
renderText({ 
  print(input$plot_brush)
  brush = input$plot_brush
  paste0("xmin: ", brush$xmin, "; ",
         "xmax: ", brush$xmax, "; ",
         "ymin: ", brush$ymin, "; ",
         "ymax: ", brush$ymax)
})
```

---

### Resizing a plot

```{r plot}
renderPlot({ 
  plot(cars) 
}, outputArgs = list(width = "75%", 
                     height = "250px")
)
```

19.7.1 A caveat

We want to emphasize that you can only use this functionality within a Shiny R Markdown document (i.e., you must set runtime: shiny in the YAML metadata). But even if that is the case, this is only applicable to pieces of Shiny code that render output without the corresponding explicit output elements in the UI. If you embed a full Shiny application in your document and try to use outputArgs, it will be ignored and print the following warning to the R Markdown console (in this case, your ui function would be something like ui = plotOutput("plot")):

Warning in `output$plot`(...) :
Unused argument: outputArgs. The argument outputArgs is only
meant to be used when embedding snippets of Shiny code in an
R Markdown code chunk (using runtime: shiny). When running a
full Shiny app, please set the output arguments directly in
the corresponding output function of your UI code.

The same will happen if you try to use outputArgs in any other context, such as inside a regular (i.e., not embedded) Shiny app. The rationale is that if you are already specifying a ui function with all the output objects made explicit, you should set their arguments directly there instead of going through this round-about way.