1

I am trying to create an rBokeh plot as an output in my Shiny app with rbokehOutput('plot') in the ui and

output$plot <- renderRbokeh({ 
figure() %>%
      ly_hexbin(x,y)
    })

in the server part. I'd like the size of the plot to be dynamic in a sense that it should dynamically resize to fill the entire plot window. I've been playing with the height and width arguments, both in the ui and server parts, but have not been able to make it work; I also tried using sizing_mode = "stretch_both" in the server part. When I display the plot in RStudio without Shiny, the plot does not fill the entire plot window either, it keeps its square shape and aspect ratio. I would like it to behave like a normal R plot, i.e. when I enlarge the plot window, the plot automatically resizes to fill the full window. I found this link, but it only deals with Python implementation. Ideally, I would like the height in Shiny to be fixed at 500px and the width to change dynamically based on the (size of) browser.

Minimal working example:

library(shiny)
library(rbokeh)

ui <- fluidPage(
  titlePanel("Hello Shiny!"),
  sidebarLayout(
    sidebarPanel(
      sliderInput('numpoint', 'Number of points to plot', min = 10, max = 1000, value = 200)
    ),
    mainPanel(
      rbokehOutput('plot', width = "98%", height = "500px")
    )
  )
)

server <- function(input, output) {
  output$plot <- renderRbokeh({
    x <- seq(1, 100, length = input$numpoint)
    y <- rnorm(input$numpoint, sd = 5)

    figure() %>%
      ly_hexbin(x,y)
  })
}

shinyApp(ui, server)

Updated MWE:

library(shiny)
library(rbokeh)

ui <- fluidPage(
  titlePanel("Hello Shiny!"),
  sidebarLayout(
    sidebarPanel(
      sliderInput('numpoint', 'Number of points to plot', min = 10, max = 1000, value = 200)
    ),
    mainPanel(
      fluidRow(
        column(12,
               rbokehOutput('plot', height = "800px")
               )
        ),
      fluidRow(
        column(12,
               plotOutput('plot1', height = "800px")
               )
      )

    )
  )
)

server <- function(input, output) {
  output$plot <- renderRbokeh({
    x <- seq(1, 100, length = input$numpoint)
    y <- rnorm(input$numpoint, sd = 5)

    figure(width = 1800, height = 800) %>%
      ly_hexbin(x,y)
  })

  output$plot1 <- renderPlot({
    x <- seq(1, 100, length = input$numpoint)
    y <- rnorm(input$numpoint, sd = 5)

    plot(x,y)
  })
}

shinyApp(ui, server)
bigreddot
  • 33,642
  • 5
  • 69
  • 122
Skumin
  • 153
  • 8

2 Answers2

0

Updating my answer..

I've added width and height into my call to figure() and the plot now re-sizes responsively.

library(shiny)
library(rbokeh)

ui <- fluidPage(
    titlePanel("Hello Shiny!"),
    sidebarLayout(
        sidebarPanel(
            sliderInput('numpoint', 'Number of points to plot', min = 10, max = 1000, value = 200)
    ),
    mainPanel(
        rbokehOutput('plot', width = "100%", height = "800px")
        )
    )
)

server <- function(input, output) {
    output$plot <- renderRbokeh({
        x <- seq(1, 100, length = input$numpoint)
        y <- rnorm(input$numpoint, sd = 5)

        figure(width = 1800, height = 800) %>%
            ly_hexbin(x,y)
    })
}

shinyApp(ui, server)

Is this what you wanted?

LuckySeedling
  • 415
  • 3
  • 7
  • Not really. See my updated MWE and compare how the two plots resize when you shrink the window width (but possibly keep the height). The base graphics is kept at constant 800px height but the rBokeh graphics is not. Moreover, when you specify `width = 800` in the call to `figure()`, the hexbins in the plot are stretched (unlike the base graphics' points which resize dynamically). – Skumin Feb 16 '17 at 15:57
  • @Skumin I know this is really old but I am having the same problem... Did you ever find a solution? – NBE Feb 07 '19 at 20:48
  • @NBE I didn't. Eventually I just switched to ggplot2, I couldn't figure it out. – Skumin Feb 22 '19 at 10:16
  • @NBE check my solution approach – mnist Oct 27 '19 at 21:47
0

Inside of your ui body, you can add the following code:

# This will dynamically set the width of the rBokeh plots
tags$head(tags$script('var dimension = [0, 0];
                          $(document).on("shiny:connected", function(e) {
                              dimension[0] = window.innerWidth;
                              dimension[1] = window.innerHeight;
                              Shiny.onInputChange("dimension", dimension);
                          });
                          $(window).resize(function(e) {
                              dimension[0] = window.innerWidth;
                              dimension[1] = window.innerHeight;
                              Shiny.onInputChange("dimension", dimension);
                          });
                          '))

Then you can use the dynamic size as an input oject like

figure(width = input$dimension[1], height = input$dimension[2],
mnist
  • 6,571
  • 1
  • 18
  • 41