我正试图在我的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)
但它似乎试图将所有内容压入主面板
这是我的应用只有一个情节的样子
这是我的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 :(得分: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)