Как можно разместить несколько сюжетов бок о бок в блестящем r?

В mainpanel я пытаюсь справиться с этой проблемой с помощью флюорита. Тем не менее, один из моих сюжетов необязателен для отображения или нет пользователями. Когда пользователь нажимает кнопку, второй график появляется под первым графиком.

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

Я играл с "align" и "widths", но ничего не изменилось.

Ответ 1

Таким образом, это произошло пару лет спустя, и, хотя остальные ответы, включая мой, все еще актуальны, я бы не стал подходить к нему сегодня. Сегодня я бы grid.arrange это используя grid.arrange из пакета gridExtra.

  • Это позволяет любое количество графиков, и может размещать их в виде сетки шахматной доски. (Я ошибочно под впечатлением, что splitLayout работал только с двумя).
  • Он имеет больше возможностей для настройки (вы можете указать строки, столбцы, верхний колонтитул, нижний колонтитул, отступы и т.д.)
  • В конечном итоге его проще использовать даже для двух графиков, поскольку выкладка в пользовательском интерфейсе очень сложная - может быть сложно предсказать, что Bootstrap будет делать с вашими элементами при изменении размера экрана.
  • Поскольку этот вопрос привлекает много внимания, я думаю, что здесь должно быть больше альтернатив.

Также стоит cowplot пакет 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)

Уступая:

enter image description here

Ответ 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"))
                          )
                )
  )
)
)

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

вы также можете играть с цифрами, показанным на рисунке ниже c ( "60%", "40%" )

введите описание изображения здесь

EDIT: Это правда, что новый ответ @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)

введите описание изображения здесь

Ответ 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 сюжета" проверил:

enter image description here

"Сделать 2 сюжета" снят:

enter image description here

Ответ 4

Я делаю пример, похожий на Майк Уайз. Тем не менее, я использую ggplot вместо qplot. Когда я делаю это, я получаю ошибку "(список) объект не может быть приведен к типу" двойной "". Любые мысли о том, почему эта ошибка происходит? Благодарю.