Issue with ggplotly legend being cropped in R Shiny application

27 views Asked by At

In my Shiny application, depending on the size of the screen, some of the legend information for my ggplotly interactive plots is cropped. Is there a way to fix this?

Here's a small example:

library(shiny)
library(ggplot2)
library(plotly)
library(tidyverse)


df <- tibble(
  year = rep(c(2015:2023), 8),
  number = c(10:18, 20:12, 13:21, 14:22, 19:11,5:13, 18:10, 8:16),
  region = c(rep("Region 1", 9), rep("Region 2", 9),
             rep("Region 3", 9), rep("Region 4", 9), 
             rep("Region 5", 9), rep("Region 6", 9),
             rep("Region 7", 9), rep("Region 8", 9))
)

# Define UI for application that draws a histogram
ui <- fluidPage(

    # Application title
    titlePanel("Example for StackOverflow"),

    # Sidebar with a slider input for number of bins 
    sidebarLayout(
        sidebarPanel(
            sliderInput("bins",
                        "Number of bins:",
                        min = 1,
                        max = 50,
                        value = 30)
        ),

        # Show a plot of the generated distribution
        mainPanel(
           uiOutput("plotpanel")
        )
    )
)

# Define server logic required to draw a histogram
server <- function(input, output) {
  
  output$plotlyObject <- renderPlotly({
    p <- ggplot(df, aes(x = year, y = number, group = region, color = region)) + 
      geom_line(stat= "identity") 
    ggplotly(p) %>% 
      plotly::layout(
        xaxis = list(
          title = list(text = "Year", font = list(size = 14, family = "Arial black")),
          tickfont = list(family = "Arial black"),
          tickangle = -45
        ),
        yaxis = list(
          title = list(text = 
                         "Number of Patients", font = list(size = 14, family = "Arial black")),
          tickfont = list(family = "Arial black")
        ),
        legend = list(
          orientation = "h",
          y = -.25,
          x = -.1
        ) ) %>% 
      plotly::config(displaylogo = FALSE,
                     modeBarButtonsToRemove = list('hoverClosestCartesian',
                                                   'hoverCompareCartesian',
                                                   'autoScale2d',
                                                   'lasso2d',
                                                   'select2d',
                                                   'zoom2d'
                     ))
  })
  
  output$plotpanel <- renderUI({
    wellPanel(
      plotlyOutput("plotlyObject", height = "400px"),
      style = "padding: 5px; border-color: darkgray"
    )
  })

}

# Run the application 
shinyApp(ui = ui, server = server)

Depending on the size of the browser window, sometimes the legend displays correctly but often it does not: plot with cropped legend plot with cropped legend

Are there settings in plotly::layout that will fix this? I haven't found a solution.

1

There are 1 answers

0
Rezious On BEST ANSWER

you must adjust the margins of the plot using the margin argument in the layout() function.

library(shiny)
library(ggplot2)
library(plotly)
library(tidyverse)


df <- tibble(
  year = rep(c(2015:2023), 8),
  number = c(10:18, 20:12, 13:21, 14:22, 19:11,5:13, 18:10, 8:16),
  region = c(rep("Region 1", 9), rep("Region 2", 9),
             rep("Region 3", 9), rep("Region 4", 9), 
             rep("Region 5", 9), rep("Region 6", 9),
             rep("Region 7", 9), rep("Region 8", 9))
)

# Define UI for application that draws a histogram
ui <- fluidPage(
  
  # Application title
  titlePanel("Example for StackOverflow"),
  
  # Sidebar with a slider input for number of bins 
  sidebarLayout(
    sidebarPanel(
      sliderInput("bins",
                  "Number of bins:",
                  min = 1,
                  max = 50,
                  value = 30)
    ),
    
    # Show a plot of the generated distribution
    mainPanel(
      uiOutput("plotpanel")
    )
  )
)

# Define server logic required to draw a histogram
server <- function(input, output) {
  
  output$plotlyObject <- renderPlotly({
    p <- ggplot(df, aes(x = year, y = number, group = region, color = region)) + 
      geom_line(stat= "identity") 
    ggplotly(p) %>% 
      plotly::layout(
        xaxis = list(
          title = list(text = "Year", font = list(size = 14, family = "Arial black")),
          tickfont = list(family = "Arial black"),
          tickangle = -45
        ),
        yaxis = list(
          title = list(text = 
                         "Number of Patients", font = list(size = 14, family = "Arial black")),
          tickfont = list(family = "Arial black")
        ),
        legend = list(
          orientation = "h",
          y = -.25,
          x = -.1
        ),
        margin = list(
          l = 100, # adjust the left margin
          r = 100, # adjust the right margin
          t = 50,  # adjust the top margin
          b = 50   # adjust the bottom margin
        )) %>% 
      plotly::config(displaylogo = FALSE,
                     modeBarButtonsToRemove = list('hoverClosestCartesian',
                                                   'hoverCompareCartesian',
                                                   'autoScale2d',
                                                   'lasso2d',
                                                   'select2d',
                                                   'zoom2d'
                     ))
  })
  
  output$plotpanel <- renderUI({
    wellPanel(
      plotlyOutput("plotlyObject", height = "400px"),
      style = "padding: 5px; border-color: darkgray"
    )
  })
  
}

# Run the application 
shinyApp(ui = ui, server = server)