web-dev-qa-db-fra.com

Comment mettre plusieurs parcelles côte à côte en r brillant?

Dans le panneau principal, j'essaie de gérer ce problème via fluidrow. Cependant, l'un de mes tracés est facultatif pour être affiché ou non par les utilisateurs. Lorsque l'utilisateur clique sur le bouton, le deuxième tracé apparaît sous le premier tracé.

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

J'ai joué avec "aligner" et "largeurs", mais rien n'a changé.

18
can.u

C'est donc quelques années plus tard, et bien que les autres réponses - y compris la mienne - soient toujours valables, ce n'est pas comme cela que je recommanderais de l'aborder aujourd'hui. Aujourd'hui, je le présenterais en utilisant le grid.arrange du package gridExtra.

  • Il permet un nombre illimité de tracés et peut les disposer sous forme de damier de grille. (J'étais par erreur sous l'impression que splitLayout ne fonctionnait qu'avec deux).
  • Il a plus de possibilités de personnalisation (vous pouvez spécifier des lignes, des colonnes, des en-têtes, un pied de page, un remplissage, etc.)
  • Il est finalement plus facile à utiliser, même pour deux tracés, car la disposition dans l'interface utilisateur est délicate - il peut être difficile de prédire ce que Bootstrap fera avec vos éléments lorsque la taille de l'écran change.
  • Étant donné que cette question reçoit beaucoup de trafic, je pense que plus d'alternative devrait être ici.

Le package cowplot mérite également d'être étudié, il offre des fonctionnalités similaires, mais je ne le connais pas très bien.

Voici un petit programme brillant démontrant que:

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)

Rendement:

enter image description here

16
Mike Wise

En utilisant l'exemple de @Mike Wise, vous pouvez également utiliser splitLayout (cellWidths = c ("50%", "50%") ... pour afficher deux tracés côte à côte.

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"))
                          )
                )
  )
)
)

server.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()})
}
)

vous pouvez également jouer avec les nombres que la figure ci-dessous montre c ("60%", "40%")

enter image description here

EDIT: Il est vrai que la nouvelle réponse de @Mike Wise donne une certaine flexibilité. Mais splitLayout peut également être utilisé avec plus de deux tracés. L'utilisation de cellWidths vous permet de modifier la taille de chaque tracé individuel. Et verticalLayout() peut également être utilisé pour ajouter des tracés verticalement (voir la section commentaire).

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)

enter image description here

36
MLavoie

Eh bien, vous ne nous avez pas donné exactement un exemple complet, mais je pense que c'est ce que vous voulez:

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()})
  }
)

Sortie

"Faire 2 tracés" coché:

enter image description here

"Faire 2 parcelles" décoché:

enter image description here

6
Mike Wise