rshinygrob

Side-by-Side Grobs Not Working with Shiny


I would like to create a Shiny document which shows two grobs alongside one another and would like the text inside each grob to be the selected value of a sliderInput.

I am able to easily output two grobs side-by-side in a non-reactive context (first example below) but obviously cannot extract the slider value. However, when I try to output them inside a renderPlot reactive context, I am able to extract the slider value, but only the second grob shows up and the connection arrow is not visible.

Can anyone offer a solution that shows both grobs and the reactive value?

---
runtime: shiny
output:
  html_document
---

```{r global-options, include = FALSE}
## set global options
knitr::opts_chunk$set(echo = F, error = F, warning = F, message = F)
```

```{r echo = F, error = F, warning = F, message = F}
## libraries
library(shiny)
library(Gmisc)
library(grid)
library(knitr)

## slider input
sliderInput("nSelect", "Select N:", min = 1, max = 10, value = 5)
```

```{r fig.width = 10, fig.height = 1}
## output grobs normally, but no way to use reactive slider values
g1 <- boxGrob(5,
        x = 0.3,
        y = 0.5)
g2 <- boxGrob(5,
        x = 0.8,
        y = 0.5)
g1
g2
connectGrob(g1, g2, type = "horizontal")
```

```{r fig.width = 10, fig.height = 1}
## output grobs using render plot (allows inputs)
renderPlot({
g3 <- boxGrob(input$nSelect,
        x = 0.3,
        y = 0.5)
g4 <- boxGrob(input$nSelect,
        x = 0.8,
        y = 0.5)
connectGrob(g3, g4, type = "horizontal")
g3
g4
})
```

enter image description here


Solution

  • Within the renderPlot you need to explicitly call print(), i.e. all you need to do is:

    renderPlot({
      g3 <- boxGrob(input$nSelect,
                    x = 0.3,
                    y = 0.5)
      g4 <- boxGrob(input$nSelect,
                    x = 0.8,
                    y = 0.5)
      print(connectGrob(g3, g4, type = "horizontal"))
      print(g3)
      print(g4)
    })
    

    This is an R-feature where anything within an expression won't print unless it is the last element, i.e. you can omit the print() for g4 as it will be printed just by being the last.