3

My problem here is, I think, an edge case for this type of problem. With that said, I've got some reproducible code here that might help a lot of people with similar issues they have, particularly the issue of changing a ggplot's plot height in RShiny (which is default set to 400px).

Here is a demo of a shiny app where the height of the ggplot is set equal to the width of the ggplot:

mydf = data.frame(x = 1:5, y = 1:5)

# User Interface
# =================
ui <- fluidPage(theme = shinytheme('united'),
                fluidRow(
                  column(width = 12, align = 'center',
                         plotOutput('myplot', height = 'auto')
                  )             
))
# ====

# Server Code 
# ==============
server <- shinyServer(function(input, output, session) {

  # 3. Create the chart
  # ===-===-===-===-===-===
  output$myplot <- renderPlot({

    ggplot(mydf, aes(x = x, y = x)) + geom_point()
  }, height = function() { session$clientData$output_myplot_width })
})
# ====

shinyApp(ui, server)

Play around with the width of the window launched by launching this shiny app. By setting height = 'auto' in the UI, and then setting height = function() { session$clientData$output_myplot_width } in the Server, the height is dynamically updated. Very good indeed.

I am working on something similar in plotly, however a significant constraint that I have is that I currently need to pass a parameter for height and width to my call of plotly(), due to the very specific way I am trying to display the markers on my plot. An example of what I am trying to do is as such:

mydf <- data.frame(x = 1:5, y = 1:5)
myplotlyfunction <- function(mydf, myplotheight) {
  plot_ly(mydf, height = myplotheight, width = myplotheight * 1.2) %>%
    add_trace(x = ~x, y = ~y, type = 'scatter', mode = 'markers')
}

# User Interface
# =================
ui <- fluidPage(theme = shinytheme('united'),
                fluidRow(
                  column(width = 12, align = 'center',
                         plotlyOutput('myplotly')
                  )
))
# ====

# Server Code
# ==============
server <- shinyServer(function(input, output, session) {

  # 3. Create the chart
  # ===-===-===-===-===-===
  output$myplotly <- renderPlotly({

    this.height <- 600
    myplotlyfunction(mydf, myplotheight = this.height)

  })
})
# ====

shinyApp(ui, server)

The specific reason why I need to pass a height and width parameter to the plot_ly() call is deserving of a post of its own, and unfortunately I haven't thought of a work around yet. Here is a real example of my plot_ly output -

enter image description here

At a high level, the marker size parameter for plot_ly scatter plots sets the marker sizes based on pixels, and my plot needs very specifically sized markers, and these marker sizes are therefore a function of the plot size.

Here is my attempt to make my plot_ly plots dynamic in Shiny, despite having to initially pass a fixed parameter to the plot_ly height. The idea is motivated on the initial ggplot() dynamic height function:

mydf <- data.frame(x = 1:5, y = 1:5)
myplotlyfunction <- function(mydf, myplotheight) {
  plot_ly(mydf, height = myplotheight, width = myplotheight * 1.2) %>%
    add_trace(x = ~x, y = ~y, type = 'scatter', mode = 'markers')
}

# User Interface
# =================
ui <- fluidPage(theme = shinytheme('united'),
                fluidRow(
                  column(width = 12, align = 'center',
                         plotlyOutput('myplotly', height = 'auto')
                  )
                ))
# ====

# Server Code
# ==============
server <- shinyServer(function(input, output, session) {

  # 3. Create the chart
  # ===-===-===-===-===-===
  output$myplotly <- renderPlotly({

    this.height <- function() { session$clientData$output_myplotly_width }
    myplotlyfunction(mydf, myplotheight = this.height)

  }, height = function() { session$clientData$output_myplotly_width })
})
# ====

shinyApp(ui, server)

This does not work, and in fact the app crashes right away.

Thank you a ton for anybody who made it to the end of this post. Any help is appreciated regarding how I can dynamically resize a plot_ly() plot in R Shiny, based on the height or width of the app window, given that the plot_ly function itself requires a height parameter. Thoughts on how to solve the underlying problem of needing a height parameter to plot_ly() in the first place are appreciated as well, but that's a separate issue (that I've posted about myself, here - Set marker size based on coordinate values, not pixels, in plotly R - and in other posts as well).

Once again, thanks a ton for any help!

5
  • 1
    +1 mostly for the amazing plot... although I agree it is an interesting problem to solve. Given that controlling for height in html should be given equal weight to such things as 'dependency hell' et al. what is driving your search? Is there a specific use case that requires the plot to be dynamically resized after rendering? Commented Dec 6, 2017 at 0:49
  • 1
    Thanks. Mainly the issue is that I don't know the window size that users of my app have - this is a tool I plan to share with the public. Not everybody has the same laptop screen / number of pixels as I do. Commented Dec 6, 2017 at 0:58
  • 1
    I understand that pain and will track this question to see how it develops. Not an answer to your specific problem, however, I used this question to guide me for a leaflet project I did and it may be of use for you. Commented Dec 6, 2017 at 1:06
  • You can have a look at the answer I gave here. It is a workaround solution to adjust height and width of plotly graph in R Shiny. Commented Dec 6, 2017 at 4:50
  • @SBista I actually came across this approach and did end up implementing something similar. I found it useful grabbing the pixel width and height of the window! Commented Dec 6, 2017 at 6:15

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.