闪亮:plotOutput()和/或renderPlot()添加的不需要的空间

时间:2017-12-07 19:42:54

标签: r ggplot2 shiny

plotOutputrenderPlot似乎在情节周围添加了一堆额外的空白区域。我已经为绘图和布局列添加了背景颜色来说明这一点。基本上,我希望完全摆脱这个空白区域,只留下蓝色区域,然后将其自身对齐到列的左侧。

我知道这可以使用width参数进行调整,但是100%auto使用它似乎无法正常工作。

谢谢!

library(shiny)
library(ggplot2)

# Create sample data
animals <- as.data.frame(
  table(Species =
          c(rep("Moose", sample(1:100, 1)),
            rep("Frog", sample(1:100, 1)),
            rep("Dragonfly", sample(1:100, 1))
          )))

server <- function(input, output) {

  output$pieChart <- renderPlot({

    # Create pie chart
    ggplot(animals, aes(x = "", y = Freq, fill = Species)) +
      geom_bar(width = 1, stat = "identity") +
      coord_polar("y", start=0) +
      theme(plot.background = element_rect(fill = "lightblue"))
  })
}

ui <- fluidPage(

  fluidRow(
    column(4, 
           style = "background-color:lightgreen",
           align = "left",
           HTML("filler<br>"),
           plotOutput("pieChart")
    )
  )
)

shinyApp(ui = ui, server = server)

enter image description here

2 个答案:

答案 0 :(得分:3)

空间由网格布局引擎添加,而不是由闪亮的任何东西添加。网格添加了空格,因为ggplot要求它保持绘图的纵横比,以确保圆是圆的。

以下是您如何看待这一点。首先,让我们以常规方式绘制图表,但让我们先手动转换为grob。

g <- ggplot(animals, aes(x = "", y = Freq, fill = Species)) +
  geom_bar(width = 1, stat = "identity") +
  coord_polar("y", start=0) +
  theme(plot.background = element_rect(fill = "lightblue"))

library(grid)
grob <- ggplotGrob(g)
grid.newpage()
grid.draw(grob)

根据封闭窗口的形状,这将生成在侧面或上/下具有空白的图:

enter image description here

enter image description here

现在让我们关闭宽高比强制执行并重新绘制:

grob$respect <- FALSE # this switches of the fixed aspect ratio
grid.newpage()
grid.draw(grob)

现在没有空白区域,但圆圈也不圆。

enter image description here

您必须将地块放入一个封闭的容器中,该容器可以在右侧和底部提供必要的空白区域。如果您愿意通过将绘图放入一个侧面和底部有空白空间的表格中,您可以使用grid进行此操作:

library(grid)
library(gtable)
# need to play around to find numbers that work
plotwidth = unit(6.1, "inch")
plotheight = unit(5, "inch")

grob <- ggplotGrob(g)
mat <- matrix(list(grob, nullGrob(), nullGrob(), nullGrob()), nrow = 2)
widths <- unit(c(1, 1), "null")
widths[1] <- plotwidth
heights <- unit(c(1, 1), "null")
heights[1] <- plotheight
gm <- gtable_matrix(NULL, mat, widths, heights)
grid.newpage()
grid.draw(gm)

enter image description here

enter image description here

这种方法的缺点是,现在,如果绘图窗口太小,绘图将不会调整大小,而是会被切断:

enter image description here

我不确定如何将绘图缩放到仍然适合窗口的最大可能尺寸。

答案 1 :(得分:3)

我对地图有类似但不完全相同的问题。我知道我想在地图中使用的宽高比(对我来说只是1:1),就像你的饼图一样,我希望它尽可能多地占据响应列的宽度,改变高度因此。但是,我不希望它大,所以我添加了一行逻辑,将其限制为400像素宽。

我的方法是绘制一个不可见的虚拟ggplot对象,然后查询客户端会话以了解其大小。然后我可以将该大小作为显式参数传递给实际所需的图。

# you need to include `session` as a third argument here
server <- function(input, output, session) {

  # blank (plot for width) ----
  output$blank <- renderPlot({
    ggplot(data.frame(x = 1), aes(NA, NA)) + geom_blank() + theme_void()
  })

  blankwidth <- reactive({
          # this is the magic that makes it work
    bw <- session$clientData$output_blank_width
    if (bw > 400) 400 else bw
  })

  blankheight <- reactive({
    blankwidth() / 1.25
    # whatever aspect ratio you need
  })

  output$plotofinterest <- renderPlot({
    ggplot(iris[sample.int(150,50),], aes(1, fill = Species)) + 
      geom_bar() + coord_polar(theta = "y")
  }, height = blankheight, width = blankwidth)
     # this is the necessary bit
}

# ui.R

ui <- fluidPage(
  fluidRow(
    column(4,
           style = "background-color:lightgreen",
           plotOutput('blank', width = '100%', height = 0),
           plotOutput('plotofinterest', inline = T)
    ),
    column(8,
           style = "background-color:lightblue",
           HTML("filler")
    )
  )
)

shinyApp(ui, server)

enter image description here

如果使窗口变窄,则绘图将小于400px上限,并且将占据整列。如果使其更宽,则右侧绿色空间会变大。我没有注意到从绘制额外的图表来从客户端获取此信息的性能损失很大。即使你拖动窗口大小来玩它,它也会很快更新。

你需要确定你想要的宽高比。 grid会自动将Claus explained这样的空格添加到不受限制的边距对中,因此只要看起来很好,就可以直观地看待它。直到它看起来不错。