我想在Shiny中创建一个用户可以使用指定为用户输入的自定义字体作为pdf下载的情节。
具体来说,我想使用pdf("plot.pdf", width = 5, height = 5, family = font.family)
之类的pdf函数,其中font.family
的值由用户指定。
下面是一个简单的示例:如果我在我的机器上运行该示例,它可以正常工作。但是,当它托管在RStudio闪亮服务器上时,我收到一条错误消息,指出无法找到指定的字体系列。我认为问题是我想要的字体无法在RStudio闪亮服务器上访问,但有没有办法可以包含它们?
server.R
shinyServer(function(input, output) {
output$distPlot <- renderPlot({
plot(1, xlim = c(0, 1), ylim = c(0, 1))
text(.5, .5, "Custom Font!!"
})
output$downloadPlot <- downloadHandler(
filename = function() {paste('CustomFont.pdf')},
content = function(file){
font.family <- input$font.family
pdf(file, width = 11, height= 8.5, family = font.family)
plot(1, xlim = c(0, 1), ylim = c(0, 1))
text(.5, .5, fonts(), cex = 10)
dev.off()
}, contentType = "image/pdf"
)
})
ui.R
shinyUI(fluidPage(
sidebarLayout(
sidebarPanel(
selectInput("font.family", "Choose Font",
choices = c("Helvetica Neue", "Times New Roman", "Arial")
),
downloadButton("downloadPlot", "Download Plot as PDF")
),
# Show a plot of the plot
mainPanel(
plotOutput("distPlot", width = "800px", height = "800px")
))))
答案 0 :(得分:0)
我有a similar problem。为了解决这个问题,很多renderPlot()功能都是使用renderImage()重新创建的,如this Shiny tutorial article中所述。然后字体渲染按照需要工作。
这是解决这个问题的代码;它也可以解决这个问题。
ui.R修改为
mainPanel(
imageOutput("myImage")
)
server.R
shinyServer(function(input, output, session) {
# A dynamically-sized plot
output$myImage <- renderImage({
# Read myImage's width and height. These are reactive values, so this
# expression will re-run whenever they change.
width <- session$clientData$output_myImage_width
height <- session$clientData$output_myImage_height
# For high-res displays, this will be greater than 1
pixelratio <- session$clientData$pixelratio
# A temp file to save the output.
outfile <- tempfile(fileext='.png')
# Generate the image file
png(outfile, width=width*pixelratio, height=height*pixelratio,
res=72*pixelratio)
plot(rnorm(100), rnorm(100), family="serif")
dev.off()
# Return a list containing the filename
list(src = outfile,
width = width,
height = height,
alt = "This is alternate text")
}, deleteFile = TRUE) # delete the temp file when finished
})