6

Consider the following rmarkdown html_notebook example:

---
output: html_notebook
runtime: shiny
---

```{r}
library(ggplot2)
library(shiny)

blank1 <- renderPlot({ ggplot() + labs(title = "Plot 1") })
blank2 <- renderPlot({ ggplot() + labs(title = "Plot 2") })
blank3 <- renderPlot({ ggplot() + labs(title = "Plot 3") })

column(6, blank1, blank2)
column(6, blank3)
```

I would like to have the plots display as:

plot-layout

I have tried a few things including:

fluidRow(
  column(6, blank1, blank2),
  column(6, blank3)
)

But I have not been able to get Plot 3 to span multiple rows.


Additional Notes (per comments):

  • I would welcome a cowplot or patchwork solution, but I require reactivity from shiny (e.g. ggplot(aes(x = input$var_select)) + ....
  • Ideally, I would like to leverage column() and/or fluidRow() to keep of the responsive-design aspects.
JasonAizkalns
  • 20,243
  • 8
  • 57
  • 116
  • 1
    You don't want to just put all the plots in one gridded image together, like with `cowplot` or `patchwork`, and then just render that one plot? – camille Dec 17 '18 at 22:38
  • @camille I don’t believe I can because I would like some interactivity which requires a reactive/shiny. – JasonAizkalns Dec 17 '18 at 23:39
  • @JasonAizkalns maybe this [thread](https://stackoverflow.com/questions/34384907/how-can-put-multiple-plots-side-by-side-in-shiny-r) could help? – Hallie Swan Dec 18 '18 at 01:58
  • That shouldn't be a problem. You can render a single `ggplot` based on reactive inputs, so you should be able to render a `ggplot` made up of other plots based on reactive inputs as well – camille Dec 18 '18 at 04:47
  • @camille Unfortunately, I do not think it's that simple. When I attempt to just "add" the plots together (i.e., pathwork), I receieve `Error in blank1 + blank2 : non-numeric argument to binary operator`. I have opened [this issue](https://github.com/thomasp85/patchwork/issues/87#issue-391956918). Moreover, using `fluidRow` and/or `column` has some additional benefits for responsive design that I would not achieve using `cowplot` or `patchwork`. – JasonAizkalns Dec 18 '18 at 14:27
  • 1
    Got it. Maybe you can add detail to the question on the responsiveness needs of the project – camille Dec 18 '18 at 14:37

2 Answers2

4

I was able to solve this by passing the heights into the renderPlot explicitly. I am still very interested in other solutions:

blank1 <- renderPlot({ ggplot() + labs(title = "Plot 1") }, height = 200)
blank2 <- renderPlot({ ggplot() + labs(title = "Plot 2") }, height = 200)
blank3 <- renderPlot({ ggplot() + labs(title = "Plot 3") }, height = 400)

fluidRow(
  column(6, fluidRow(blank1), fluidRow(blank2)),
  column(6, fluidRow(blank3))
)

It's not perfect from a responsive design approach, but it'll work.

Shiny with Plot Heights

JasonAizkalns
  • 20,243
  • 8
  • 57
  • 116
1

You could try something like the following which sets the margins on the plot and columns to 0 and sets the heights of plot 3 to be twice that of plots 1 and 2.

---
output: html_notebook
runtime: shiny
---

<!-- break between code folding button and fluid layout -->
<br>

```{r echo=FALSE, message=FALSE}
library(ggplot2)
library(shiny)

# create the plots telling ggplot to use 0 margins

p1 <- ggplot() +
      theme(plot.margin = unit(c(0,0,0,0), "cm"),
            panel.background=element_rect(fill = "lightgreen"))
p2 <- ggplot() +
      theme(plot.margin = unit(c(0,0,0,0), "cm"),
            panel.background=element_rect(fill = "lightblue"))
p3 <- ggplot() +
      theme(plot.margin = unit(c(0,0,0,0), "cm"),
            panel.background=element_rect(fill = "orange"))

# Set the heights in renderPlot so that plot 3 is twice the height
# of the other 2 plots

blank1 <- renderPlot({p1}, height=200)
blank2 <- renderPlot({p2}, height=200)
blank3 <- renderPlot({p3}, height=400)

# Tell the fluid layout to set padding and margin to 0 for the column divs

fluidPage(
  fluidRow(
    column(6, blank1, blank2, offset=0, style='padding:0px;margin:0px;'),
    column(6, blank3, offset=0, style='padding:0px;margin:0px;')
  )
)
```

Which results in the following:

enter image description here

Mike N.
  • 1,662
  • 1
  • 13
  • 19