[英]no output with reactive shiny plots
Here are my initial trappings for a Shiny app that takes a user-uploaded image and returns a plot of the compressed image with the user-specified number of principal components. 这是我对Shiny应用程序的最初陷阱,该应用程序获取用户上传的图像,并返回包含用户指定数量的主成分的压缩图像的图。 Code recycled from https://ryancquan.com/blog/2014/10/07/image-compression-pca/ 从https://ryancquan.com/blog/2014/10/07/image-compression-pca/回收的代码
I get no error but the plot never appears in mainPanel. 我没有收到任何错误,但该图从未出现在mainPanel中。
ui.R 用户界面
library(shiny)
shinyUI(pageWithSidebar(
headerPanel("PCA compression"),
sidebarPanel(
fileInput('selfie', "SELECT PNG", accept=c('image/png')),
sliderInput("PCAdim", "Number of dimensions to be reduced to:", min=3, max=5, value = 4),
actionButton("exec", "EXECUTE")
),
mainPanel(
imageOutput('Image')
)
))
server.R 服务器
library(shiny)
shinyServer(function(input, output, session) {
inFile <- reactive({
inFile <- input$selfie
})
PCAdim <- reactive({
PCAdim <- input$PCAdim
})
ProjectImage <- function(prcomp.obj, pc.num) {
# project image onto n principal components
scores <- prcomp.obj$x
loadings <- prcomp.obj$rotation
img.proj <- scores[, c(1:pc.num)] %*% t(loadings[, c(1:pc.num)])
return(img.proj)
}
SplitImage <- function(rgb.array) {
# decompose image into RGB elements
rgb.list <- list()
for (i in 1:dim(rgb.array)[3]) {
rgb.list[[i]] <- rgb.array[, , i]
}
return(rgb.list)
}
ReduceDimsPNG <- function(png.file, pc.num, display.only=TRUE) {
# reduce dimensions of PNG image
rgb.array <- readPNG(png.file)
rgb.list <- SplitImage(rgb.array)
# apply pca and reproject onto new principal components
rgb.list <- lapply(rgb.list, prcomp, center=FALSE)
rgb.proj <- lapply(rgb.list, ProjectImage, pc.num=pc.num)
# restore original dimensions
restored.img <- abind(rgb.proj, along=3)
}
eventReactive(input$exec, {
output$Image <- renderImage({
outfile <- tempfile(fileext='.png')
writePNG(ReduceDimsPNG(inFile(), PCAdim(), target = outfile))
renderPlot(png(outfile))
dev.off()
})
})
})
In addition to the problems pointed out by @Jota, there are a couple of other problems: 除了@Jota指出的问题外,还有其他一些问题:
fileInput
returns a dataframe, not a file name, so ReduceDimsPNG(png.file = inFile(), ...)
will generate an error. fileInput
返回一个数据帧,而不是文件名,因此ReduceDimsPNG(png.file = inFile(), ...)
将生成错误。 ReduceDimsPNG(inFile(), PCAdim(), target = outfile))
将括号错误地放置在ReduceDimsPNG(inFile(), PCAdim(), target = outfile))
renderImage
should return a list containing the filename, eg list(src = outfile, contentType = 'image/png', ...)
renderImage
应该返回一个包含文件名的列表,例如list(src = outfile, contentType = 'image/png', ...)
The following single-file Shiny app, which corrects the problems above, works on my machine: 以下单文件Shiny应用程序可解决上述问题,可在我的计算机上运行:
ui <- pageWithSidebar(
headerPanel("PCA compression"),
sidebarPanel(
fileInput('selfie', "SELECT PNG", accept=c('image/png')),
sliderInput("PCAdim", "Number of dimensions to be reduced to:", min=3, max=5, value = 4),
actionButton("exec", "EXECUTE")
),
mainPanel(
imageOutput('Image')
)
)
server <- function(input, output, session) {
inFile <- reactive({
inFile <- input$selfie
})
PCAdim <- reactive({
PCAdim <- input$PCAdim
})
ProjectImage <- function(prcomp.obj, pc.num) {
# project image onto n principal components
scores <- prcomp.obj$x
loadings <- prcomp.obj$rotation
img.proj <- scores[, c(1:pc.num)] %*% t(loadings[, c(1:pc.num)])
return(img.proj)
}
SplitImage <- function(rgb.array) {
# decompose image into RGB elements
rgb.list <- list()
for (i in 1:dim(rgb.array)[3]) {
rgb.list[[i]] <- rgb.array[, , i]
}
return(rgb.list)
}
ReduceDimsPNG <- function(png.file, pc.num, display.only=TRUE) {
# reduce dimensions of PNG image
rgb.array <- png::readPNG(png.file)
rgb.list <- SplitImage(rgb.array)
# apply pca and reproject onto new principal components
rgb.list <- lapply(rgb.list, prcomp, center=FALSE)
rgb.proj <- lapply(rgb.list, ProjectImage, pc.num=pc.num)
# restore original dimensions
restored.img <- abind::abind(rgb.proj, along=3)
}
img.array <- eventReactive(input$exec, {
ReduceDimsPNG(inFile()$datapath[1], PCAdim())
})
output$Image <- renderImage({
outfile <- tempfile(fileext='.png')
png::writePNG(img.array(), target = outfile)
list(src = outfile, contentType = 'image/png')}, deleteFile = TRUE
)
}
shinyApp(ui = ui, server = server)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.