2015-11-02 113 views
2

我試圖在我的Shiny應用程序的主面板中顯示多個圖。R中的多個圖Shiny

我使用從R cookbook

multiplot <- function(..., plotlist=NULL, file, cols=1, layout=NULL) { 
library(grid) 

# Make a list from the ... arguments and plotlist 
plots <- c(list(...), plotlist) 

numPlots = length(plots) 

# If layout is NULL, then use 'cols' to determine layout 
if (is.null(layout)) { 
    # Make the panel 
    # ncol: Number of columns of plots 
    # nrow: Number of rows needed, calculated from # of cols 
    layout <- matrix(seq(1, cols * ceiling(numPlots/cols)), 
        ncol = cols, nrow = ceiling(numPlots/cols)) 
} 

if (numPlots==1) { 
    print(plots[[1]]) 

} else { 
    # Set up the page 
    grid.newpage() 
    pushViewport(viewport(layout = grid.layout(nrow(layout), ncol(layout)))) 

    # Make each plot, in the correct location 
    for (i in 1:numPlots) { 
    # Get the i,j matrix positions of the regions that contain this subplot 
    matchidx <- as.data.frame(which(layout == i, arr.ind = TRUE)) 

    print(plots[[i]], vp = viewport(layout.pos.row = matchidx$row, 
            layout.pos.col = matchidx$col)) 
    } 
} 
} 

的的multiplot功能,然後調用的multiplot

multiplot(p1,p2,p3,p4,p5,p6, cols=1) 

但它看起來像它試圖在到主面板

壓扁一切

這裏就是我的應用程序看起來像只有一個情節

enter image description here

這裏是我的ui.R

shinyUI(fluidPage(


    titlePanel("Baseball"), 

    sidebarLayout(
    sidebarPanel(
     selectInput(
     "var", label = "Choose a group to visualize", 
     choices =c(Overall = "overall", Offense = "offense", Pitchers = "pitchers", Simpsons = "simpsons"), 
     selected = "offense") 
    ), 

    mainPanel(
     plotOutput("plotOffense") 

    ) 
    ) 
    ) 
    ) 

我需要使用的東西,而不是mainPanel中,允許更多的圖形放置在瀏覽器中?

+0

你有一個HTML容器,你正在放置你的陰謀.''ultilot'與它的大小無關。您可能會滿意於簡單地增加此容器的高度,即plotOutput(「plotOffense」,height =「800px」)'。你可以讓這個更「程序化」,但它可能需要深入鑽研。 – jenesaisquoi

+0

,但一個更簡單的解決方案是不使用'多功能'功能,併爲每個圖形單獨製作'renderPlot'和'plotOutput'。 – jenesaisquoi

+0

@bunk謝謝,我會考慮改變身高。你的第二個評論是我的備份計劃。但這些圖將取決於用戶在下拉列表中選擇的內容。我必須找出一種方法來捕獲UI中的用戶輸入.R – rvisio

回答

6

嗯,其實只是兩件事情要發生:plotOutput應該叫創建DIV的實際輸出,並renderPlot需要調用格式化以正確的方式情節。所以,下面是一些可以動態實現這個功能的函數,並且讓您可以使用寬度/高度/列數(類似於多槽)進行操作,只是採用閃亮的方式。同樣參考gist

我把事情分解成函數,但它也可以直接放入服務器函數中。

編輯:我忘了提及,寬度和高度輸入框是文本,並且應該是有效的CSS,因此它可以是10,10px或10%。

library(shiny) 
library(ggplot2) 

## Some sample data 
dat <- setNames(data.frame(matrix(runif(100),10)), letters[1:10]) 
dat$time <- seq(nrow(dat)) 

## Make some random plots because it looks cooler 
## But you would just define your 10 different plots 
rndmPlot <- function(input) 
    sample(list(geom_line(), geom_bar(stat='identity'), geom_point(), geom_jitter(), 
       geom_density(aes_string(x=input$var), inherit.aes=FALSE)), 1) 

makePlotContainers <- function(n, ncol=2, prefix="plot", height=100, width="100%", ...) { 
    ## Validate inputs 
    validateCssUnit(width) 
    validateCssUnit(height) 

    ## Construct plotOutputs 
    lst <- lapply(seq.int(n), function(i) 
     plotOutput(sprintf('%s_%g', prefix, i), height=height, width=width)) 

    ## Make columns 
    lst <- lapply(split(lst, (seq.int(n)-1)%/%ncol), function(x) column(12/ncol, x)) 
    do.call(tagList, lst) 
} 

renderPlots <- function(n, input, output, prefix="plot") { 
    for (i in seq.int(n)) { 
     local({ 
      ii <- i # need i evaluated here 
      ## These would be your 10 plots instead 
      output[[sprintf('%s_%g', prefix, ii)]] <- renderPlot({ 
       ggplot(dat, aes_string(x='time', y=input$var)) + rndmPlot(input) 
      }) 
     }) 
    } 
} 

ui <- shinyUI(
    fluidPage(
     sidebarLayout(
      sidebarPanel(
       sliderInput('nplots', 'Number of Plots', min=1, max=10, value=8), 
       selectInput("var", label = "Choose", choices=letters[1:10]), 
       textInput('height', 'Plot Height', value="100"), 
       textInput('width', 'Width', value="100%"), 
       sliderInput('ncol', 'Columns', min=1, max=3, value=2) 
      ), 
      mainPanel(
       uiOutput('plots') 
      ) 
     ) 
    ) 
) 

server <- shinyServer(function(input, output) { 
    output$plots <- renderUI({ 
     makePlotContainers(input$nplots, ncol=input$ncol, height=input$height, width=input$width) 
    }) 
    observeEvent(input$nplots, renderPlots(input$nplots, input, output)) 
}) 

shinyApp(ui, server) 
+0

謝謝!當我今晚下班回家時,我會試一試。 – rvisio