Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support for plots with absolute dimensions #4194

Open
jbengler opened this issue Feb 26, 2025 · 2 comments
Open

Support for plots with absolute dimensions #4194

jbengler opened this issue Feb 26, 2025 · 2 comments

Comments

@jbengler
Copy link

Dear shiny team,

sometimes it makes sense to choose absolute dimensions for a ggplot to get more control over the aspect ratio and the visual proportions of the elements in the plot.

One way to do this is patchwork::plot_layout(), but also the new ggplot2 release will acquire this capability in ggplot2::theme(). See here:
tidyverse/ggplot2#6094

Currently, shiny is already respecting the absolute dimensions of the plot. However, with big window sizes we get a lot of white space around the plot and with small window sizes the plot gets cut off. See reprex below.

What would be the ideal behavior?
It would be great if the plot image would still be scaled to fill all available space, however more in the sense of a responsive web image. See https://www.w3schools.com/howto/howto_css_image_responsive.asp

Do you see a way to implement this?
Or is there a workaround that already exists in current shiny?

Thanks for you thoughts & Best wishes
Jan

library(shiny)
library(bslib)
library(tidyverse)
library(patchwork)

ui <- page_sidebar(
  title = "Absolute dimensions",
  sidebar = sidebar(),
  plotOutput(outputId = "distPlot")
)

server <- function(input, output) {
  output$distPlot <- renderPlot({
    ggplot(faithful, aes(eruptions, waiting)) +
      geom_point() +
      patchwork::plot_layout(heights = unit(50, "mm"), widths = unit(100, "mm"))
  })
}

shinyApp(ui = ui, server = server)
@gadenbuie
Copy link
Member

The image you're creating is responsive and is filling the whole area available to it. It's the plot_layout() height and width constraint that are placing the plot in the center of a large empty region.

In your example app, you can copy the plot image or inspect the element in the browser to see that it's making a large plot with lots of empty space.

Example
Image

If you want to enforce the plot having a specific aspect ratio, there are some CSS tricks you can use. For example, you could remove the plot_layout() constraints and use a div with a specific aspect ratio:

  div(
    style="aspect-ratio: 2;",
    plotOutput(outputId = "distPlot", height="100%")
  )

@jbengler
Copy link
Author

Thank you for your prompt answer!

Is there also a way to keep the plot_layout()?

In the example below I have reduced the white margin in the image file. However, I did not find a way to make this image responsive in the sense that it fills up its parent container without distortion.

library(shiny)
library(bslib)
library(tidyverse)
library(patchwork)

ui <- page_sidebar(
  title = "Absolute dimensions",
  sidebar = sidebar(),
  plotOutput(outputId = "distPlot")
)

server <- function(input, output) {
  output$distPlot <- renderPlot({
    ggplot(faithful, aes(eruptions, waiting)) +
      geom_point()
  }, width = 300, height = 200)
}

shinyApp(ui = ui, server = server)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants