1

I'm making an R Shiny application that uses a choropleth to display some data. The plotly version works well, but I can't find how to adjust its sizing to make full use of the space.
It always looks square-ish, I'd want a rectangle that's as wide as the div that the plot is made in.

Here is a small example app:

library(shiny)
library(plotly)

country_data <- data.frame(
  country_short = c("DEU", "USA", "BRA", "CAN", "MEX"),
  points = c(10, 20, 30, 40, 50)
)


ui <- fluidPage(
  div(style="width:1400px",
      plotlyOutput("choro")
      )
)

server <- function(input, output, session) {
  output$choro <- renderPlotly({
    plot_ly(country_data, 
             width = 1400,
            type = "choropleth",
            z = ~ points, 
            locations = ~ country_short,
            marker = list(
              line = list(
                color = "white"
              )
            ),
            showscale = F
    ) %>%
      layout(geo = list(
        landcolor = rgb(0.9, 0.9, 0.9),
        countrycolor = "white",
        coastlinecolor = "white",
        showland = T,
        showcountries = T,
        showframe = F,
        projection = list(type = "Mercator"),
        margin = list(l = 0, r = 0)
        )
      )
  }) 
}

shinyApp(ui, server)

I'd expect the plot to be 1400px wide, but when I inspect element it, the width is 670px. How can I change this, either in R with plotly options, or with CSS?

5
  • Set height / width in the layout like %>% layout( width = 1400, height = 800, geo = list(... as per this - no need for a div in your ui, just use ui <- fluidPage(plotlyOutput("choro")). I will just answer as a comment, since it's a duplicate question. Commented Apr 25 at 12:53
  • The rectangle containing the map is still 670 pixels wide, even though the plot-container is wide. So the actual plot still doesn't take up all the width. Commented Apr 25 at 12:59
  • the requirement of fitting into the parent div and also having no margins makes this a) much more complicated that I initially thought, and b) a unique and valid question. I hope my answer is what you had in mind! Commented Apr 25 at 13:36
  • 1
    Is there a particular reason for wrapping the plotlyOutput in (another) div? You can pass the height and width directly to plotlyOutput. If you are trying to always fill the screen, I'd suggest using relative css units. Commented Apr 28 at 7:33
  • I wrote it to simulate a more complex page having a certain element, in which a plot resides, of a certain width. Relative css units generally work, but it seems that choropleths specifically have restrictions regarding when the plot will fill all of the alloted space. Commented Apr 28 at 7:40

1 Answer 1

2

To set the rectangle as wide as the plot's div, you can

  1. set the height:700px & width:1400px in your div - width / height = 2
  2. use plotlyOutput("choro", height = "100%") instead - the height is set to 400px as per default but it needs to be adjusted to 100% in order to use all the space.
  3. add margin = list(l = 0, r = 0, t = 0, b = 0, pad = 0) to the layout to remove all padding and margins

library(shiny)
library(plotly)
country_data <- data.frame(
  country_short = c("DEU", "USA", "BRA", "CAN", "MEX"),
  points = c(10, 20, 30, 40, 50)
)
ui <- fluidPage(
  div(style="width:1400px; height:700px;", # add height to div
      plotlyOutput("choro", height = "100%")  # Set height to 100%
  )
)
server <- function(input, output, session) {
  output$choro <- renderPlotly({
    plot_ly(country_data, 
            type = "choropleth",
            z = ~ points, 
            locations = ~ country_short,
            marker = list(
              line = list(
                color = "white"
              )
            ),
            showscale = F
    ) %>%
      layout(
        margin = list(l = 0, r = 0, t = 0, b = 0, pad = 0),  # Zero margins at layout level
        geo = list(
          landcolor = rgb(0.9, 0.9, 0.9),
          countrycolor = "white",
          coastlinecolor = "white",
          showland = T,
          showcountries = T,
          showframe = F,
          projection = list(type = "Mercator")
        )
      )
  }) 
}
shinyApp(ui, server)

giving

out

Sign up to request clarification or add additional context in comments.

2 Comments

Thank you! So from what I gather, the plot width is necessarily dependent on the height? I can't make a 1400px wide choropleth unless the size is at least 700px?
@mkranj yes that seems to be the case. You could make an image of of the plot (ggsave+ggplot or plotly + webshot) and stretch this image to whatever dimensions you want maybe but that would get rid of the interactivity of the plot :/

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.