0

I have a ggplot in Shiny, which uses geom_point to plot some data. I have it setup so that when a checkbox is checked, an aesthetic is added which colours the data into two separate variables. This also creates a legend. My problem is that when this legend appears, it 'takes' space from the plot and the plot becomes slightly smaller. Is there a way I can fix the size of the plot so that the legend appears without altering the plot size?

ui <- fluidPage(
  titlePanel("Transfers Analysis App"),

  sidebarLayout(
    sidebarPanel(
      checkboxInput("Outage", "Show Outages", FALSE)
    ),
    mainPanel(
      plotOutput("plot1", height = "600px", width = "100%", hover = hoverOpts(id = "plot_hover")),
      verbatimTextOutput("hover_info")
    )
  )
)

server <- function(input, output) {

  output$plot1 <- renderPlot({
    Outage <- input$Outage

    g <- ggplot(data, aes(Date, NUMBER_OF_TRANSFERS)) + geom_point() 

    if (Outage == TRUE) 
      g <- g + geom_point(aes(color = Outage))  + scale_colour_manual(breaks = c("Outage", "No Outage", "Day After an Outage", "Both"), name= "Legend", values=c( "black", "red", "blue")) + theme(legend.position="bottom")

    plot(g)
  })
}

shinyApp(ui, server)

note: my actual code has a lot more features in than this which I have cut out for simplicity.

K. Rohde
  • 9,439
  • 1
  • 31
  • 51
lewisnix21
  • 111
  • 2
  • 7
  • 1
    Since you are going the extra mile, can you make sure your code is actually able to run? (Syntax and data.) – K. Rohde Jan 04 '18 at 10:48
  • Data is missing here, plus few brackets... – Mal_a Jan 04 '18 at 11:06
  • Sorry for the quality of my code (I'm new to both stack and R), I'm not sure if I am able to provide the data as this is a company project I'm working on. I realise this doesn't help much but I thought maybe someone might be able to tell me where I'm going wrong or suggest some functions/techniques just by looking at my code alone? Thanks – lewisnix21 Jan 04 '18 at 11:54

1 Answers1

2

Maybe someone has a better idea but here is a suggestion. You could plot only the legend of the same graphic. You did not provide a dataset so I am using the iris dataset as an example. If you click on outage it will produce a legend at the bottom of the first graph. If unclick, it will produce a blank plot you won't see. As you can see the legend will not change the size of your first graph.

Using this post (How to plot just the legends in ggplot2?), you could:

#function to extract the legend
g_legend<-function(a.gplot){ 
  tmp <- ggplot_gtable(ggplot_build(a.gplot)) 
  leg <- which(sapply(tmp$grobs, function(x) x$name) == "guide-box") 
  legend <- tmp$grobs[[leg]] 
  return(legend)} 

ui <- fluidPage(
  titlePanel("Transfers Analysis App"),

  sidebarLayout(
    sidebarPanel(
      checkboxInput("Outage", "Show Outages", FALSE)
    ),
    mainPanel(
      plotOutput("plot1", height = "600px", width = "100%", hover = hoverOpts(id = "plot_hover")),
      plotOutput("plot2"),
      verbatimTextOutput("hover_info")
    )
  )
)

server <- function(input, output) {

  output$plot1 <- renderPlot({
    Outage <- input$Outage

    g <- ggplot(iris, aes(Sepal.Length, Sepal.Width)) + geom_point() 

    if (Outage == TRUE) 
      g <- g + geom_point(aes(color = Species))  + scale_colour_manual(breaks = c("setosa", "virginica", "versicolor"), values=c( "black", "red", "blue")) + 
      theme(legend.position="none") 
    plot(g)

  })


  output$plot2 <- renderPlot({

    Outage <- input$Outage

    if (Outage == TRUE) {
      g <- ggplot(iris, aes(Sepal.Length, Sepal.Width)) + geom_point() 

      g <- g + geom_point(aes(color = Species))  + scale_colour_manual(breaks = c("setosa", "virginica", "versicolor"), name= "Legend", values=c( "black", "red", "blue")) + 
        theme(legend.position="bottom") +
        theme(legend.text=element_text(size=15)) # you can change the size of the legend

      legend <- g_legend(g) 
      grid.draw(legend) 
    } else {
      g <- ggplot()  + theme_bw(base_size=0) +
        theme(axis.line = element_line(colour = "black"),
              panel.grid.major = element_blank(),
              panel.grid.minor = element_blank(),
              panel.border = element_blank(),
              panel.background = element_blank()) 

      plot(g)
    }

  })  
}


shinyApp(ui, server)
MLavoie
  • 9,671
  • 41
  • 36
  • 56