R Shiny中的多个图

时间:2015-11-02 02:20:36

标签: r ggplot2 shiny

我正试图在我的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(p1,p2,p3,p4,p5,p6, cols=1)

但它似乎试图将所有内容压入主面板

enter image description here

这是我的应用只有一个情节的样子

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来允许在浏览器中放置更多图形?

1 个答案:

答案 0 :(得分:7)

嗯,实际上只有两件事情要发生:应该调用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)