我正在尝试保存在 shiny
应用程序中创建的 ggplot2
对象。基本上,此代码允许上传 .xlsx
文件,并从某些选项中进行选择后创建图。然后,我添加了一个下载按钮,以便用户可以下载他们创建的图。我正在使用 downloadHandler()
和 grDevices :: png()
。按下按钮确实会导致下载 .png
文件,但是当我打开它时,它只是一个空白的白色正方形。我好亲密!任何帮助将非常感激。谢谢。
#initialize
图书馆(闪亮)
库(ggplot2)
图书馆(purrr)
图书馆(dplyr)
图书馆(密谋)
#示例数据
数据(虹膜)
#制定一些因素
#easier让ggplot2根据类型控制绘图(颜色,填充)
数据(mtcars)
uvals <-sapply(mtcars,function(x){length(unique(x))})
mtcars <-map_if(mtcars,uvals <4,as.factor)%>%
as.data.frame()
#gggglot2主题
.theme <-主题(
axis.line = element_line(colour ='gray',size = .75),
panel.background = element_blank(),
plot.background = element_blank()
)
#应用界面
ui <-(pageWithSidebar(
#标题
headerPanel(“选择选项”),
#input
sidebarPanel
(
#输入:选择一个文件----
fileInput(“ file1”,“选择xlsx文件”,
多个= TRUE,
接受= c(“。xlsx”)),
#水平线----
标签$ hr(),
#download按钮
fluidPage(downloadButton('down')),
#输入:选择要显示的内容
selectInput(“ dataset”,“ Data:”,
选择= list(iris =“ iris”,mtcars =“ mtcars”,
upload_file =“ inFile”),selected = NULL),
selectInput(“ xaxis”,“ X轴:”,options = NULL),
selectInput(“ yaxis”,“ Y轴:”,options = NULL),
selectInput(“ fill”,“ Fill:”,options = NULL),
selectInput(“ group”,“ Group:”,options = NULL),
selectInput(“ plot.type”,“绘图类型:”,
list(boxplot =“ boxplot”,直方图=“ histogram”,密度=“密度”,bar =“ bar”)
),
checkboxInput(“ show.points”,“显示点”,TRUE)
),
#输出
mainPanel(
h3(textOutput(“ caption”)),
#h3(htmlOutput(“ caption”)),
uiOutput(“ plot”)#取决于输入
)
))
#每个呼叫的闪亮服务器端代码
服务器<功能(输入,输出,会话){
#update组和
#基于数据的变量
观察({
#browser()
if(!exists(input $ dataset))return()#确保上传存在
var.opts <-colnames(get(input $ dataset))
updateSelectInput(session,“ xaxis”,options = var.opts)
updateSelectInput(session,“ yaxis”,options = var.opts)
updateSelectInput(session,“ fill”,options = var.opts)
updateSelectInput(session,“ group”,options = var.opts)
})
输出$标题<-renderText({
开关(input $ plot.type,
“ boxplot” =“ Boxplot”,
“ histogram” =“直方图”,
“密度” =“密度图”,
“ bar” =“条形图”)
})
output $ plot <-renderUI({
plotOutput(“ p”)
})
#获取数据对象
get_data <-reactive({
if(!exists(input $ dataset))return()#如果没有上传
check <-function(x){is.null(x)|| x ==“”}
if(check(input $ dataset))return()
obj <-list(data = get(input $ dataset),
yaxis = input $ yaxis,
xaxis = input $ xaxis,
填充=输入$填充,
组=输入$组
)
#require全部设为继续
if(任何(sapply(obj,check)))return()
#确保选择有机会更新
检查<功能(obj){
!all(c(obj $ yaxis,obj $ xaxis,obj $ fill,obj $ group)%in%名称(obj $ data))
}
if(check(obj))return()
对象
})
#使用ggplot2进行绘图
输出$ p <-renderPlot({
plot.obj <-get_data()
#绘图条件
if(is.null(plot.obj))return()
#确保变量和组已加载
if(plot.obj $ yaxis ==“” | plot.obj $ xaxis ==“” | plot.obj $ fill ==“” | plot.obj $ group ==“”)return()
#图类型
plot.type <-switch(input $ plot.type,
“ boxplot” = geom_boxplot(),
“直方图” = geom_histogram(alpha = 0.5,position =“ identity”),
“密度” = geom_density(alpha = .75),
“ bar” = geom_bar(position =“ dodge”)
)
if(input $ plot.type ==“ boxplot”){#控制一维或二维图形
p <-ggplot(plot.obj $ data,
aes_string(
x = plot.obj $ xaxis,
y = plot.obj $ yaxis,
fill = plot.obj $ fill,#让类型确定绘图
组= plot.obj $ group
)
)+ plot.type
如果(input $ show.points == TRUE)
{
p <-p + geom_point(颜色='黑色',alpha = 0.5,位置='抖动')
}
}其他{
p <-ggplot(plot.obj $ data,
aes_string(
x = plot.obj $ xaxis,
填充= plot.obj $填充,
组= plot.obj $ group
#color = as.factor(plot.obj $ group)
)
)+ plot.type
}
p <-p + labs(
填充=输入$填充,
x =“”,
y =输入$ yaxis
)+
。主题
打印(p)
})
#设置上传文件
upload_data <-active({
inFile <-输入$ file1
如果(is.null(inFile))
返回(NULL)
#也可以存储在reactValues中
read_excel(inFile $ datapath)
})
watchEvent(input $ file1,{
inFile <<-upload_data()
})
#downloadHandler包含2个参数作为函数,即文件名,内容
output $ down <-downloadHandler(
文件名= function(){
paste(input $ dataset,“ png”,sep =“。”)
},
#content是带有参数文件的函数。内容将情节写入设备
内容=函数(文件){
png(file)#打开png设备
GGPLOT的p#
dev.off()#关闭设备
}
)
}
#创建闪亮的应用程序----
ShinyApp(用户界面,服务器)
答案 0 :(得分:4)
我以评论的形式回应,但我知道这样做有些困难,因此我将发布完整的修订代码以使其更加清晰。
我通常建议在render*()
调用中不要做太多事情。而是在单独的reactive()
对象中设置要创建的对象,并仅在renderPlot()
中引用该对象。在下面的代码中,我将创建情节的所有代码移到名为reactive
的{{1}}对象中,然后可以在p
中引用它进行下载。
ggsave()