【问题标题】:How can put multiple plots side-by-side in shiny r?如何在闪亮的 r 中并排放置多个图?
【发布时间】:2016-03-26 21:23:54
【问题描述】:

在主面板中,我尝试通过流体行处理这个问题。但是,我的一个情节是可选的,是否由用户显示。当用户点击按钮时,第二个图出现在第一个图的下方。

   fluidRow(
      column(2, align="right",
             plotOutput(outputId = "plotgraph1", width  = "500px",height = "400px"),  
             plotOutput(outputId = "plotgraph2", width  = "500px",height = "400px")
      ))

我玩过“对齐”和“宽度”,但没有任何改变。

【问题讨论】:

    标签: r plot ggplot2 shiny


    【解决方案1】:

    所以这是几年后的事了,虽然其他答案——包括我的——仍然有效,但我今天不建议这样做。今天我将使用gridExtra 包中的grid.arrange 进行布局。

    • 它允许任意数量的地块,并且可以将它们布置成类似棋盘格的网格。 (我错误地认为splitLayout 只与两个合作过)。
    • 它有更多的自定义可能性(您可以指定行、列、页眉、页脚、填充等)
    • 最终它更易于使用,即使是两个绘图,因为在 UI 中的布局很挑剔 - 当屏幕尺寸发生变化时,很难预测 Bootstrap 将如何处理您的元素。
    • 由于这个问题的访问量很大,我觉得这里应该有更多的选择。

    cowplot 包也值得研究,它提供了类似的功能,但我不太熟悉。

    这是一个闪亮的小程序,展示了这一点:

    library(shiny)
    library(ggplot2)
    library(gridExtra)
    
    u <- shinyUI(fluidPage(
      titlePanel("title panel"),
      sidebarLayout(position = "left",
          sidebarPanel("sidebar panel",
               checkboxInput("donum1", "Make #1 plot", value = T),
               checkboxInput("donum2", "Make #2 plot", value = F),
               checkboxInput("donum3", "Make #3 plot", value = F),
               sliderInput("wt1","Weight 1",min=1,max=10,value=1),
               sliderInput("wt2","Weight 2",min=1,max=10,value=1),
               sliderInput("wt3","Weight 3",min=1,max=10,value=1)
          ),
          mainPanel("main panel",
              column(6,plotOutput(outputId="plotgraph", width="500px",height="400px"))
    ))))
    
    s <- shinyServer(function(input, output) 
    {
      set.seed(123)
      pt1 <- reactive({
        if (!input$donum1) return(NULL)
        qplot(rnorm(500),fill=I("red"),binwidth=0.2,main="plotgraph1")
        })
      pt2 <- reactive({
        if (!input$donum2) return(NULL)
        qplot(rnorm(500),fill=I("blue"),binwidth=0.2,main="plotgraph2")
      })
      pt3 <- reactive({
        if (!input$donum3) return(NULL)
        qplot(rnorm(500),fill=I("green"),binwidth=0.2,main="plotgraph3")
      })
      output$plotgraph = renderPlot({
        ptlist <- list(pt1(),pt2(),pt3())
        wtlist <- c(input$wt1,input$wt2,input$wt3)
        # remove the null plots from ptlist and wtlist
        to_delete <- !sapply(ptlist,is.null)
        ptlist <- ptlist[to_delete] 
        wtlist <- wtlist[to_delete]
        if (length(ptlist)==0) return(NULL)
    
        grid.arrange(grobs=ptlist,widths=wtlist,ncol=length(ptlist))
      })
    })
    shinyApp(u,s)
    

    产量:

    【讨论】:

      【解决方案2】:

      使用@Mike Wise 示例,您还可以使用 splitLayout(cellWidths = c("50%", "50%")... 并排显示两个图。

      ui..R

      library(shiny)
      
      shinyUI(fluidPage(
        titlePanel("title panel"),
      
        sidebarLayout(position = "left",
                      sidebarPanel("sidebar panel",
                                   checkboxInput("do2", "Make 2 plots", value = T)
                      ),
                      mainPanel("main panel",
                                fluidRow(
                                  splitLayout(cellWidths = c("50%", "50%"), plotOutput("plotgraph1"), plotOutput("plotgraph2"))
                                )
                      )
        )
      )
      )
      

      服务器.R

      shinyServer(function(input, output) 
      {
        set.seed(1234)
        pt1 <- qplot(rnorm(500),fill=I("red"),binwidth=0.2,title="plotgraph1")
        pt2 <- reactive({
          input$do2
          if (input$do2){
            return(qplot(rnorm(500),fill=I("blue"),binwidth=0.2,title="plotgraph2"))
          } else {
            return(NULL)
          }
        })
        output$plotgraph1 = renderPlot({pt1})
        output$plotgraph2 = renderPlot({pt2()})
      }
      )
      

      你也可以玩下图中的数字 c("60%", "40%")

      编辑:@Mike Wise 的新答案确实提供了一些灵活性。但是splitLayout 也可以用于两个以上的地块。使用cellWidths 可以更改每个绘图的大小。并且verticalLayout() 也可以用于垂直添加图(见评论部分)。

      library(shiny)
      library(ggplot2)
      u<- shinyUI(fluidPage(
        titlePanel("title panel"),
      
        sidebarLayout(position = "left",
                      sidebarPanel("sidebar panel",
                                   checkboxInput("do2", "Make 2 plots", value = T)
                      ),
                      mainPanel("main panel",
                                fluidRow(
                                  splitLayout(style = "border: 1px solid silver:", cellWidths = c(300,200,100), 
                                  plotOutput("plotgraph1"), 
                                  plotOutput("plotgraph2"),
                                  plotOutput("plotgraph3")
                                  )
                                )
                      )
        )
      )
      )
      s <- shinyServer(function(input, output){
        set.seed(1234)
        pt1 <- qplot(rnorm(500),fill=I("red"),binwidth=0.2,title="plotgraph1")
        pt3 <- qplot(rnorm(600),fill=I("blue"),binwidth=0.2,title="plotgraph3")
        pt2 <- reactive({
          input$do2
          if (input$do2){
            return(qplot(rnorm(500),fill=I("blue"),binwidth=0.2,title="plotgraph2"))
          } else {
            return(NULL)
          }
        })
        output$plotgraph1 = renderPlot({pt1})
        output$plotgraph2 = renderPlot({pt2()})
        output$plotgraph3 = renderPlot({pt3}
        )
      })
      
      shinyApp(u,s)
      

      【讨论】:

      • 不错的一个。为你 +1 :)
      • 他也应该给我+1。还有你。
      • 是否可以将其分成 4 个相等的部分并有一个 2 x 2 的矩阵和 4 个图?
      • @liza,实际上是的,这是可能的。你只需要使用fluidRow(verticalLayout( splitLayout(cellWidths = c("50%", "50%"), plotOutput("distPlot"), plotOutput("distPlot2"))), splitLayout(cellWidths = c("50% ", "50%"), plotOutput("distPlot3"), plotOutput("distPlot4"))
      • 对我的 DataTable 用例和 grid.arrange() 不起作用的并排绘图非常有用。谢谢!
      【解决方案3】:

      嗯,你没有给我们一个完整的例子,但我认为这就是你想要的:

      ui.r

      # ui.R
      
      shinyUI(fluidPage(
        titlePanel("title panel"),
      
        sidebarLayout(position = "left",
          sidebarPanel("sidebar panel",
            checkboxInput("do2", "Make 2 plots", value = T)
            ),
            mainPanel("main panel",
              fluidRow(
                column(6,plotOutput(outputId="plotgraph1", width="300px",height="300px")),  
                column(6,plotOutput(outputId="plotgraph2", width="300px",height="300px"))
              )
            )
          )
        )
      )
      

      server.r

      # server.r
      
      library(ggplot2)
      
      shinyServer(function(input, output) 
        {
        set.seed(1234)
        pt1 <- qplot(rnorm(500),fill=I("red"),binwidth=0.2,title="plotgraph1")
          pt2 <- reactive({
            input$do2
            if (input$do2){
              return(qplot(rnorm(500),fill=I("blue"),binwidth=0.2,title="plotgraph2"))
            } else {
              return(NULL)
            }
          })
          output$plotgraph1 = renderPlot({pt1})
          output$plotgraph2 = renderPlot({pt2()})
        }
      )
      

      输出

      “制作 2 个地块”选中:

      “制作 2 个地块”未选中:

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2014-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-03-05
        • 2020-08-28
        • 2017-12-12
        • 2019-06-14
        • 1970-01-01
        相关资源
        最近更新 更多