Search code examples
rggplot2shinyflexdashboard

ggplot2 plot stretches in flexdashboard and cuts bottom


I want to show a few different plots on my Shiny application, separating them in little named sections (using Markdown's ###). However, the plots I'm printing inside those sections have their bottoms cut. Not only that, but when I change their data-height attribute, they stretch just to guarantee that they'll still be cut.

enter image description here

enter image description here

I might be able to set a data-height value that's large enough that it won't cut the image at all, but by then it will be extremely deformed. How do I keep the plot the same size while resizing the section it's in? Or even better, is it possible to make it so the section size automatically fits to the plot size?

--- EDIT:

---
title: "title"
author: "author"
date: "date"
output: 
  flexdashboard::flex_dashboard:
    orientation: columns
    vertical_layout: scroll
    logo: ""
    favicon: ""
    source_code: embed
    runtime: shiny
runtime: shiny
---

```{r setup, include=FALSE}
library (tidyverse)
```

# Tab 1

## Column

### Section 1

```{r echo=FALSE}
# Data processing

inputPanel (
    # inputs
)

renderPlot ({
    # Data processing

    step = 0.05
    max = step * ceiling(max(retention_rate$high) / step)
    min = step * floor(min(retention_rate$low) / step)

    ggplot (retention_rate,
            aes (x = dsi, y = median,
                 ymin = low, ymax = high,
                 colour = ab_group, fill = ab_group)) +
        theme (panel.background = element_rect (fill = 'white'),
               panel.grid.major = element_line (colour = 'grey90', size = 0.20),
               panel.grid.minor = element_line (colour = 'grey90', size = 0.10),
               plot.title = element_text (lineheight = 1.15),
               axis.title.y = element_text (angle = 0),
               axis.title = element_text (size = 10),
               text = element_text (size = 10),
               legend.title = element_text (size = 10),
               strip.text = element_text (size = 10, angle = 0),
               plot.caption = element_text (hjust = 0.5, size = 9)) +
        geom_vline (xintercept = c (1, 3, 7, 14, 28),
                    colour = 'gray80', linetype = 2, size = 0.4) +
        geom_line () +
        geom_ribbon (aes (colour = NULL), alpha = 0.2) +
        scale_x_continuous (breaks = seq (0, max (retention_rate$dsi), 5)) +
        scale_y_continuous (limits = c  (min, max),
                            breaks = seq (min, max, step),
                            labels = sprintf ('%.0f %%', 100 * seq (min, max, step))) +
        scale_colour_brewer (palette = 'Dark2') +
        scale_fill_brewer (palette = 'Dark2') +
        facet_grid (source~country) +
        labs(x = '',
             y = '',
             colour = '',
             fill = '',
             title = '',
             subtitle = '')
})
```

### Days Active

```{r echo=FALSE}
# Data processing

inputPanel (
    # inputs
)

renderPlot ({
    # Data processing

    step = 0.5
    max = step * ceiling(max(da$high) / step)
    min = 0

    ggplot (da, aes (x = '', y = median,
                     ymin = low, ymax = high,
                     colour = ab_group, fill = ab_group)) +
        theme (panel.background = element_rect (fill = 'white'),
               panel.grid.major = element_line (colour = 'grey90', size = 0.20),
               panel.grid.minor = element_line (colour = 'grey90', size = 0.10),
               plot.title = element_text (lineheight = 1.15),
               axis.title.y = element_text (angle = 0),
               axis.title = element_text (size = 10),
               text = element_text (size = 10),
               legend.title = element_text (size = 10),
               strip.text = element_text (size = 10, angle = 0),
               plot.caption = element_text (hjust = 0.5, size = 9)) +
        geom_col (aes (colour = NULL), position = 'dodge', alpha = 0.60, width = 2 / 3) +
        geom_errorbar (position = position_dodge (width = 2 / 3), width = 1 / 3) +
        geom_text (position = position_dodge (width = 2 / 3),
                   aes (label = sprintf ('%.2f', median)), #hjust = - 1 / (nrow (da) - 1),
                   vjust = -1) +
        scale_y_continuous (limits = c (min, max),
                            breaks = seq (min, max, step)) +
        scale_colour_brewer (palette = 'Dark2') +
        scale_fill_brewer (palette = 'Dark2') +
        facet_grid (source~country) +
        labs (x = '',
              y = '',
              fill = '', colour = '',
              title = '',
              subtitle = '')
})
```

Solution

  • I am unable to reproduce your example because I don't have retention_rate, so I used mtcars data, setting renderPlot height to 1000 to simulate the cropping.

    I used miniContentPanel from library(miniUI) with scrollable = TRUE in the upper plot. Now you have a vertical scrollbar unlike the lower plot.

    enter image description here

    ---
    title: "title"
    author: "author"
    date: "date"
    output: 
      flexdashboard::flex_dashboard:
      orientation: columns
    vertical_layout: scroll
    logo: ""
    favicon: ""
    source_code: embed
    runtime: shiny
    ---
    
    ```{r, setup, include=FALSE}
    library (tidyverse)
    library(miniUI)
    
    ```
    
    # Tab 1
    
    ## Column
    
    ### Section 1
    
    ```{r, echo=FALSE}
    # Data processing
    
    inputPanel (
      # inputs
    )
    
    ## Upper plot with miniContentPanel and scrollable = TRUE
    miniContentPanel(
      renderPlot ({
        ggplot(mtcars,aes(x=mpg,y=cyl))+
          geom_point()
      },height=1000),
      scrollable = TRUE)
    
    ```
    
    ### Days Active
    
    ```{r, echo=FALSE}
    # Data processing
    
    inputPanel (
      # inputs
    )
    
    ## lower plot without miniContentPanel ----
    renderPlot({
      ggplot(mtcars,aes(x=gear,y=wt))+
        geom_point()},
    height=1000)
    
    ```