Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
722 views
in Technique[技术] by (71.8m points)

ggplot2 - Multiple Plots in R Shiny

I'm attempting to display multiple plots in my main panel in my Shiny app.

I am using the multiplot function from 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))
  }
}
}

And then calling multiplot

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

But it looks like it's trying to squish everything in to the main panel

enter image description here

Here is what my app looks like with only one plot

enter image description here

Here is my 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")

    )
    )
    )
    )

Do I need to be using something instead of mainPanel that allows for more graphics to be placed in the browser?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

Well, there are really just two things that have to happen: plotOutput should be called to create the div for the actual output, and renderPlot needs to be called to format the plot in the correct way. So, here are a some functions that can do this dynamically, and let you play with the width/height/number of columns, similar to the multiplot, only in a shiny way. Refer to this gist as well.

I separated things into functions, but it could be just put straight into the server function as well.

EDIT: I forgot to mention, the width and height entry boxes are text, and should be valid CSS, so it could be 10, 10px, or 10% for example.

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)

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

2.1m questions

2.1m answers

60 comments

57.0k users

...